实例详解thinkphp6使用jwt认证
2724
本篇文章给大家带来了关于thinkphp的相关知识,其中主要介绍了使用jwt认证的问题,下面一起来看一下,希望对大家有帮助。
thinkphp6 使用jwt
客户端使用用户名和密码请求登录
服务端收到请求,验证用户名和密码
验证成功后,服务端会签发一个token,再把这个token返回给客户端
客户端收到token后可以把它存储起来,比如放到cookie中
客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据
安装 jwt 扩展
- composer require firebase/php-jwt
安装之后在 vender 目录下的 firebase 文件夹下
调用 JWT里面的 encode 和 decode方法进行生成token和验证token
项目app 目录下的 common.php全局文件使用的 ,做成了公共方法,由于我是多应用的,所以就写在了api下面的common.php,大家可以根据自己需求适当调整
首先 引入 JWT ,然后写两个方法,生成验签和验证token。
- <?php
- use \Firebase\JWT\JWT;
- use Firebase\JWT\Key;
- // 应用公共文件
- /**
- * 生成验签
- * @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(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
- $res['info'] = "签名不正确";
- return $res;
- }catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
- $res['info'] = "token失效";
- return $res;
- }catch(\Firebase\JWT\ExpiredException $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 控制器
- <?php
- declare (strict_types = 1);
- namespace app\api\controller;
- use think\facade\Db;
- use think\Request;
- 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中间件
- <?php
- declare (strict_types = 1);
- namespace app\middleware;
- class Api{
- /**
- * 处理请求
- *
- * @param \think\Request $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请求。
本文网址:https://www.zztuku.com/index.php/detail-12437.html
站长图库 - 实例详解thinkphp6使用jwt认证
申明:本文转载于《CSDN》,如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!