站长资讯网
最全最丰富的资讯网站

实例详解thinkphp6使用jwt认证

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

实例详解thinkphp6使用jwt认证

推荐学习:《PHP视频教程》

thinkphp6 使用jwt

  1. 客户端使用用户名和密码请求登录
  2. 服务端收到请求,验证用户名和密码
  3. 验证成功后,服务端会签发一个token,再把这个token返回给客户端
  4. 客户端收到token后可以把它存储起来,比如放到cookie中
  5. 客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
  6. 服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据

安装 jwt 扩展

composer require firebase/php-jwt

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

实例详解thinkphp6使用jwt认证

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

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

实例详解thinkphp6使用jwt认证

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

<?phpuse FirebaseJWTJWT;use FirebaseJWTKey;// 应用公共文件/**  * 生成验签  * @param $uid 用户id  * @return mixed  */function signToken($uid){     $key='abcdefg';         //自定义的一个随机字串用户于加密中常用的 盐  salt     $token=array(         "iss"=>$key,        //签发者 可以为空         "aud"=>'',          //面象的用户,可以为空         "iat"=>time(),      //签发时间         "nbf"=>time(),      //在什么时候jwt开始生效         "exp"=> time()+30,  //token 过期时间         "data"=>[           //记录的uid的信息             'uid'=>$uid,         ]     );     $jwt = JWT::encode($token, $key, "HS256");  //生成了 token     return $jwt;}/**  * 验证token  * @param $token  * @return array|int[]  */function checkToken($token){     $key='abcdefg';     //自定义的一个随机字串用户于加密中常用的 盐  salt     $res['status'] = false;     try {         JWT::$leeway    = 60;//当前时间减去60,把时间留点余地         $decoded        = JWT::decode($token, new Key($key, 'HS256')); //HS256方式,这里要和签发的时候对应         $arr            = (array)$decoded;         $res['status']  = 200;         $res['data']    =(array)$arr['data'];         return $res;      } catch(FirebaseJWTSignatureInvalidException $e) { //签名不正确         $res['info']    = "签名不正确";         return $res;     }catch(FirebaseJWTBeforeValidException $e) { // 签名在某个时间点之后才能用         $res['info']    = "token失效";         return $res;     }catch(FirebaseJWTExpiredException $e) { // token过期         $res['info']    = "token过期";         return $res;     }catch(Exception $e) { //其他错误         $res['info']    = "未知错误";         return $res;     }}

使用jwt生成token

    /**      * 使用jwt生成token字符串      */     public function setJwtToken()     {         $uid = input('uid'); // 接收生成token字符串 如:123         $token = signToken($uid);         // 生成字符串: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhYmNkZWZnIiwiYXVkIjoiIiwiaWF0IjoxNjQxNDUwMTU0LCJuYmYiOjE2NDE0NTAxNTcsImV4cCI6MTY0MTQ1NzM1NCwiZGF0YSI6eyJ1aWQiOiIxMjMifX0.I_GAkMsOhtEpIPkizCuQA-b9H6ovSovWx0AwAYI-b0s         echo $token;die;     }      /**      * 使用jwt验证token字符串      */     public function checkJwtToken()     {         $token  = input('token'); // 接收生成token字符串         $result = checkToken($token);         // Array ( [status] => 200 [data] => Array ( [uid] => 123 ) )         print_r($result);die;     }

创建 user 控制器

<?phpdeclare (strict_types = 1);namespace appapicontroller;use thinkfacadeDb;use thinkRequest;class User{     public function login(Request $request)     {         if ($request->isPost()){             $username = $request->param('username','','trim');             $password = $request->param('password','','trim');              //查询数据库             $user = Db::name('user')->where('username',$username)->find();              if (!$user){                 return json(['status' => 'fail','msg' => '用户名不存在']);             }             if ($user['password']!==md5($password)){                 return json(['status' => 'fail','msg' => '密码错误']);             }             $getToken = $this->token($user);             return json(['status' => 'success','msg' => '登陆成功','token' => $getToken]);         }     }     public function token($user)     {         $uid = $user['username']; // 接收生成token字符串 如:123         $token = signToken($uid);         dd($token);     }     /**      * 验证token      */     public function chToken()     {         $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhYmNkZWZnIiwiYXVkIjoiIiwiaWF0IjoxNjQ4MDkwMDkyLCJuYmYiOjE2NDgwOTAwOTIsImV4cCI6MTY0ODA5MDEyMiwiZGF0YSI6eyJ1aWQiOiJcdTVmMjBcdTRlMDlcdTk4Y2UifX0.oJFpNcZ6stMymOCbD-meX0IPEIYLYNcwKxhMItF2cMw';         $result = checkToken($token);         // Array ( [status] => 200 [data] => Array ( [uid] => 123 ) )         print_r($result);die;     }}

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

创建api中间件

<?phpdeclare (strict_types = 1);namespace appmiddleware;class Api{     /**      * 处理请求      *      * @param thinkRequest $request      * @param Closure       $next      * @return Response      */     public function handle($request, Closure $next)     {         //toke 合法性验证         $header = $request->header();         //判读请求头里有没有token         if(!isset($header['token'])){             return json(['code'=>440,'msg'=>'request must with token']);         }         $token = $header['token'];          try {             // token 合法             $token = checkToken($token);         }catch (Exception $e){             return json(['code'=>440,'msg'=>'invalid token']);         }          return $next($request);     }}

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

我是程序员峰峰,一名爱学习,爱折腾的程序员。

推荐学习:《PHP视频教程》

赞(0)
分享到: 更多 (0)