什么是JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
为什么使用JWT
传统的基于session的认证,在随着不同客户端用户的增加,独立的服务器无法承载更多的用户。每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。并且获取数据受限于当前服务器,扩展性不高。
基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到 跨站请求伪造(CSRF) 的攻击。
JWT将信息存储在token中,因为http是无状态协议,完美解决上边的问题。
JWT原理
使用流程
- 用户使用用户名密码来请求服务器
- 服务器进行验证用户的信息
- 服务器通过验证发送给用户一个token
- 客户端存储token,并在每次请求时附送上这个token值
- 服务端验证token值,并返回数据
JWT构成
- header:声明类型以及加密方法。
- playload:承载主要信息,主要包括要保存的数据(不建议存储用户名和密码),以及有效时间exp,签发时间iat,生效时间nbf等
- sign:签名规则。一般会有一个由客户端和服务端约定好的秘钥key,再根据不同的加密方式进行验证。
JWT使用(php)
-
先引入JWT包(composer安装)
{ "require": { "firebase/php-jwt": "5.2.0" } }
这个只是JWT包中的一个,支持SHA系列的算法。
-
封装一个token生成解析类
<?php namespace app\lib\token; use Firebase\JWT\JWT; class TokenJWT { /** * @param $key string 秘钥 * @param $tokenData array 需要保存的业务数据 * @param $expire int 失效时间 * @return string */ function JWTEncode(string $key, array $tokenData, int $expire) { $payload = [ "iat" => time(), // 签发时间 "nbf" => time(), // 生效时间 "exp" => $expire, // 失效时间 ]; $payload = array_merge($payload , $tokenData); $jwt = JWT::encode($payload, $key); return $jwt; } /** * @param $key string 秘钥 * @param $jwt string 客户端传递的token * @param $leeway int 这是一个缓冲值,单位为秒。在验证的时候,用来延长当前时间JWT::$timestamp ($leeway这个时间尽量短,或者不设置) * @return array */ function JWTDecode($jwt, $key, $leeway) { JWT::$leeway = $leeway; $decoded = JWT::decode($jwt, $key, array('HS256')); return (array)$decoded; } }
-
我们去调用它
生成token:function createToken(string $key, array $tokenData, int $expire) { $key = '123456'; $data = [ "iss" => "http://example.org", "aud" => "http://example.com", ]; $jwt = (new TokenJWT())->JWTEncode($key, $data, time()+86400) echo $jwt; }
根据token获取信息:
function getDataByToken(string $key, array $tokenData, int $expire) { $key = '123456'; $token= "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjE2MTI1ODc4OTYsImV4cCI6MTM1NzAwMDAwMH0.5OgPa1tQLah06lCIdof80y-AjkrEh6CF5L4qjAR6D3k"; $data = (new TokenJWT())->JWTDecode($token, $key, 60) dump($jwt); }