对于新手朋友在项目开发中经常会遇到跨域请求的问题,如果不是经验很丰富的情况下前后端经常会相互甩锅。其实这中间的根本原因是没有搞懂HTTP请求原理。
当然本篇笔记,波波并不想谈HTTP请求的底层原理和过程。简单分享下JWT的使用。前后端分离的项目不仅需要处理跨域,而且还有用户鉴权的问题。JWT正是一位牛人写出来解决这个问题的。
一、JWT后端使用指南
1、引入JWT类库
- composer require firebase/php-jwt
2、简单用法:
- use \Firebase\JWT\JWT;
- $key = "example_key";
- $token = array(
- "iss" => "http://example.org",
- "aud" => "http://example.com",
- "iat" => 1356999524,
- "nbf" => 1357000000
- );
- $jwt = JWT::encode($token, $key);
- $decoded = JWT::decode($jwt, $key, array('HS256'));
- print_r($decoded);
- $decoded_array = (array) $decoded;
- JWT::$leeway = 60; // $leeway in seconds
- $decoded = JWT::decode($jwt, $key, array('HS256'));
3、异常捕获
- try {
- $arr = $jwt::decode($token, $key, array('HS256'));
- } catch (\Exception $e) { // token验证失败
- return json(['code' => 0, 'msg' => $e->getMessage()],400)->send();
- }catch (ExpiredException $e){ // 过期
- return json(['code' => 0, 'msg' => $e->getMessage()],400)->send();
- }
二、JWT前端使用
1、用户登陆请求后获取用户信息,前端技术可以存放在cookie或local storage中。
2、前端请求时可以在body中加上token信息,也可以将token放在HTTP请求的head中。究竟放哪里,需要与后端技术协商,这涉及接口鉴权的业务逻辑。前后端约定好即可。
三、签名
签名是为了保障传输数据的安全性,防止篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
- HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
当然这个公式不是唯一的,前后端统一即可。
四、总结
(1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
(2)JWT 不加密的情况下,不能将秘密数据写入 JWT。
(3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
(4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
(5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
(6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。