thinkphp5.1 使用jwt

更新于 2023-02-07 14:37 574
专栏: PHP 标签: thinkphp JWT

介绍

JWT是JSON Web Token的缩写,是为了在网络应用环境间传递声明而执行的- -种基于JSON的开放标准((RFC 7519)。JWT本身没有定义任何技术实现,它只是定义了一种基于Token的会话管理的规则,涵盖Token需要包含的标准内容和Token的生成过程,特别适用于分布式站点的单点登录(SSO) 场景。

相关网站

本文所使用的库(github)
jwt官网

开始使用

1.安装firebase/php-jwt

首先我们需要使用 Composer 来为我们的 TP5.1 项目安装 JWT。在 TP5.1 项目中使用命令行运行以下代码即可自动下载安装:

  1. composer require firebase/php-jwt

装好了之后在 vendor 目录下可以看到 firebase 文件夹

2.流程说明

使用 JWT 生成 Token 需要三个参数,分别是负载 (payload)、密匙 (key)、加密算法 (algorithm),其中密匙是由自己规定的,加密算法从源码中选取一种设置,之后接收到传来的 Token 时需要使用此密匙来验证接收到的 Token,负载部分为想要传输的信息,其中有一些字段为官方定义的,但是并不是必需的,除此之外我们还可以定义一些自己的私有字段用来传输额外信息,例如以上实例中将签发时间和生效时间设置为当前时间,Token 过期时间为当前时间的七天后,并加上了自己定义的是否是测试的字段。定义好这些信息后就可以使用 JWT 的静态方法 encode 来生成一个 Token。

3.创建一个 Webapi 模块下的 Jwt 控制器

开始编码

  1. <?php
  2. namespace app\Webapi\controller;
  3. use Firebase\JWT\JWT;
  4. use Firebase\JWT\Key;
  5. use think\Controller;
  6. class Index extends Controller {
  7. private $key = 'sun'; //定义加密所需的密钥(自定义的,这里我用姓名缩写来做密钥)
  8. private $algorithm = 'HS256'; //定义加密所需的加密算法(翻看源码得知:支持的算法有'ES384'、'ES256'、'HS256'、'HS384')
  9. public function index() {
  10. $token = input('post.token'); //接收前端传来的jwt下生成的token
  11. $res = $this->verifyToken($token); //验证token合法性
  12. if ($res == 'fail') {
  13. return json(['code' => 450, 'msg' => 'token验证失败!']);
  14. }
  15. if ($res == 'redirect') {
  16. return json(['code' => 300, 'msg' => 'token过期!']);
  17. }
  18. #接下来写jwt通过后的业务逻辑
  19. // 解析加密值
  20. return json(['code' => 200, 'data' => $res]);
  21. }
  22. /**
  23. * 获取jwt生成的token,返回给前端
  24. * @return string
  25. */
  26. public function getToken() {
  27. //jwt载荷(负载) 格式如下非必须
  28. $payload = [
  29. 'iss' => 'anbin', //签发人(自定义该jwt编写人,官方字段:非必需)
  30. 'iat' => time(), //签发时间(官方字段:非必需)
  31. 'exp' => (time() + 3600) * 24 * 7, //过期时间(自定义设置7天后过期,官方字段:非必需)
  32. 'nbf' => time(), //生效时间(在什么时间之后该jwt才可用,官方字段:非必需)
  33. 'test' => true, //自定义字段
  34. 'refresh_token'=>"adsfsadfsadf"
  35. ];
  36. return $token = JWT::encode($payload, $this->key, $this->algorithm);
  37. }
  38. //前端携带token进行验证
  39. public function verifyToken($token) {
  40. try {
  41. //验证通过
  42. $result = JWT::decode($token, new Key($this->key, $this->algorithm));
  43. return $result;
  44. } catch (\Exception $e) {
  45. //dump($e->getmessage()); //打印得到错误信息
  46. //令牌过期
  47. if ($e->getmessage() == 'Expired token') {
  48. return 'redirect';
  49. }
  50. //验证失败
  51. return 'fail';
  52. }
  53. }
  54. }

4.前后端请求流程说明:

  • 1.前端先访问getToken接口得到jwt生成的token
  • 2.然后携带刚刚生成token请求index接口进行验证。
  • 3.验证失败返回json,验证通过即可编写业务逻辑代码。

5.小提示:

前端可以根据后端设置的 token 有效期时间,把 token 在有效时间内存储起来,而不是每次都请求后端接口来重新获取 token。

JWT优缺点

JWT拥有基于Token的会话管理方式所拥有的一切优势,不依赖Cookie,使得其可以防止CSRF攻击,也能在禁用Cookie的浏览器环境中正常运行。
而JWT的最大优势是服务端不再需要存储Session,使得服务端认证鉴权业务可以方便扩展,避免存储Session所需要引入的Redis等组件,降低了系统架构复杂度。但这也是JWT最大的劣势,由于有效期存储在Token中,JWT Token-旦签发,就会在有效期内-直可用,无法在服务端废止,当用户进行登出操作,只能依赖客户端删除掉本地存储的JWT Token,如果需要禁用用户,单纯使用JWT就无法做到了。

参考:JWT详解
thinkphp5.1下使用 jwt 进行验证

BLOG

搜索文章