实例详解thinkphp6使用jwt认证

 2724

本篇文章给大家带来了关于thinkphp的相关知识,其中主要介绍了使用jwt认证的问题,下面一起来看一下,希望对大家有帮助。

实例详解thinkphp6使用jwt认证

thinkphp6 使用jwt

客户端使用用户名和密码请求登录

服务端收到请求,验证用户名和密码

验证成功后,服务端会签发一个token,再把这个token返回给客户端

客户端收到token后可以把它存储起来,比如放到cookie中

客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带

服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据

安装 jwt 扩展

  1. composer require firebase/php-jwt

安装之后在 vender 目录下的 firebase 文件夹下

实例详解thinkphp6使用jwt认证


调用 JWT里面的 encode 和 decode方法进行生成token和验证token

项目app 目录下的 common.php全局文件使用的 ,做成了公共方法,由于我是多应用的,所以就写在了api下面的common.php,大家可以根据自己需求适当调整


实例详解thinkphp6使用jwt认证


首先 引入 JWT ,然后写两个方法,生成验签和验证token。

  1. <?php
  2. use \Firebase\JWT\JWT;
  3. use Firebase\JWT\Key;
  4. // 应用公共文件
  5.  
  6. /**
  7.  * 生成验签
  8.  * @param $uid 用户id
  9.  * @return mixed
  10.  */
  11. function signToken($uid){
  12.     $key='abcdefg';         //自定义的一个随机字串用户于加密中常用的 盐  salt
  13.     $token=array(
  14.         "iss"=>$key,        //签发者 可以为空
  15.         "aud"=>'',          //面象的用户,可以为空
  16.         "iat"=>time(),      //签发时间
  17.         "nbf"=>time(),      //在什么时候jwt开始生效
  18.         "exp"=> time()+30,  //token 过期时间
  19.         "data"=>[           //记录的uid的信息
  20.             'uid'=>$uid,
  21.         ]
  22.     );
  23.     $jwt = JWT::encode($token, $key, "HS256");  //生成了 token
  24.     return $jwt;
  25. }
  26. /**
  27.  * 验证token
  28.  * @param $token
  29.  * @return array|int[]
  30.  */
  31. function checkToken($token){
  32.     $key='abcdefg';     //自定义的一个随机字串用户于加密中常用的 盐  salt
  33.     $res['status'] = false;
  34.     try {
  35.         JWT::$leeway    = 60;//当前时间减去60,把时间留点余地
  36.         $decoded        = JWT::decode($token, new Key($key, 'HS256')); //HS256方式,这里要和签发的时候对应
  37.         $arr            = (array)$decoded;
  38.         $res['status']  = 200;
  39.         $res['data']    =(array)$arr['data'];
  40.         return $res;
  41.  
  42.     } catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
  43.         $res['info']    = "签名不正确";
  44.         return $res;
  45.     }catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
  46.         $res['info']    = "token失效";
  47.         return $res;
  48.     }catch(\Firebase\JWT\ExpiredException $e) { // token过期
  49.         $res['info']    = "token过期";
  50.         return $res;
  51.     }catch(Exception $e) { //其他错误
  52.         $res['info']    = "未知错误";
  53.         return $res;
  54.     }
  55. }

使用jwt生成token

  1. /**
  2.  * 使用jwt生成token字符串
  3.  */
  4. public function setJwtToken()
  5. {
  6.     $uid = input('uid'); // 接收生成token字符串 如:123
  7.     $token = signToken($uid);
  8.     // 生成字符串: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhYmNkZWZnIiwiYXVkIjoiIiwiaWF0IjoxNjQxNDUwMTU0LCJuYmYiOjE2NDE0NTAxNTcsImV4cCI6MTY0MTQ1NzM1NCwiZGF0YSI6eyJ1aWQiOiIxMjMifX0.I_GAkMsOhtEpIPkizCuQA-b9H6ovSovWx0AwAYI-b0s
  9.     echo $token;die;
  10. }
  11.  
  12. /**
  13.  * 使用jwt验证token字符串
  14.  */
  15. public function checkJwtToken()
  16. {
  17.     $token  = input('token'); // 接收生成token字符串
  18.     $result = checkToken($token);
  19.     // Array ( [status] => 200 [data] => Array ( [uid] => 123 ) )
  20.     print_r($result);die;
  21. }

创建 user 控制器

  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\api\controller;
  4. use think\facade\Db;
  5. use think\Request;
  6.  
  7. class User{
  8.     public function login(Request $request)
  9.     {
  10.         if ($request->isPost()){
  11.             $username = $request->param('username','','trim');
  12.             $password = $request->param('password','','trim');
  13.  
  14.             //查询数据库
  15.             $user = Db::name('user')->where('username',$username)->find();
  16.  
  17.             if (!$user){
  18.                 return json(['status' => 'fail','msg' => '用户名不存在']);
  19.             }
  20.             if ($user['password']!==md5($password)){
  21.                 return json(['status' => 'fail','msg' => '密码错误']);
  22.             }
  23.             $getToken = $this->token($user);
  24.             return json(['status' => 'success','msg' => '登陆成功','token' => $getToken]);
  25.         }
  26.     }
  27.     public function token($user)
  28.     {
  29.         $uid = $user['username']; // 接收生成token字符串 如:123
  30.         $token = signToken($uid);
  31.         dd($token);
  32.     }
  33.     /**
  34.      * 验证token
  35.      */
  36.     public function chToken()
  37.     {
  38.         $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhYmNkZWZnIiwiYXVkIjoiIiwiaWF0IjoxNjQ4MDkwMDkyLCJuYmYiOjE2NDgwOTAwOTIsImV4cCI6MTY0ODA5MDEyMiwiZGF0YSI6eyJ1aWQiOiJcdTVmMjBcdTRlMDlcdTk4Y2UifX0.oJFpNcZ6stMymOCbD-meX0IPEIYLYNcwKxhMItF2cMw';
  39.         $result = checkToken($token);
  40.         // Array ( [status] => 200 [data] => Array ( [uid] => 123 ) )
  41.         print_r($result);die;
  42.     }
  43. }

用户登录成功返回给前端token,前端将token存储起来,在下次请求的时候头部携带着这个token,后端接受token,在中间件中进行验证


创建api中间件

  1. <?php
  2. declare (strict_types = 1);
  3.  
  4. namespace app\middleware;
  5. class Api{
  6.     /**
  7.      * 处理请求
  8.      *
  9.      * @param \think\Request $request
  10.      * @param \Closure       $next
  11.      * @return Response
  12.      */
  13.     public function handle($request, \Closure $next)
  14.     {
  15.         //toke 合法性验证
  16.         $header = $request->header();
  17.         //判读请求头里有没有token
  18.         if(!isset($header['token'])){
  19.             return json(['code'=>440,'msg'=>'request must with token']);
  20.         }
  21.         $token = $header['token'];
  22.  
  23.         try {
  24.             // token 合法
  25.             $token = checkToken($token);
  26.         }catch (\Exception $e){
  27.             return json(['code'=>440,'msg'=>'invalid token']);
  28.         }
  29.  
  30.         return $next($request);
  31.     }
  32. }

最后,关于如何处理token过期的问题,有两种解决办法,第一种就是,将token的时间设置长一些,这样token就不会过期,但是这样就有一个弊端,一旦客户端拿到了这个token就相当于有了密钥,主动权也就掌握在了用户的手上。所以不推荐这种方案。第二种就是,后端处理,当token过期的时候重新获取token,将新的token传给前端,前端在将新的token存储起来,替换掉原来的token,下一次请求的时候就携带着新的token请求。


TAG标签:
本文网址:https://www.zztuku.com/index.php/detail-12437.html
站长图库 - 实例详解thinkphp6使用jwt认证
申明:本文转载于《CSDN》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐