AD编程:「文章」TP框架中使用jwt技术来实现Token

2022-10-11 21:40:52 106 0
魁首哥

1.介绍jwt:

  • token生成的两种类型:
    • 使用随机函数生成token,在服务器使用session保存token;
    • 使用jwt生成和验证token。
  • jwt生成token的优劣
    • 常规token的情况介绍
    • jwt的优点:服务器无需存储,只需验证;适合多端进行验证;可以保留相应的用户信息,如权限等;

2.安装jwt:在 vscode编辑器中,按照 ctrl+` 打开。注意查看一下目录是否正确,然后输入以下命令

 composer require firebase/php-jwt  

3.在User数据模型中创建 createToken方法:

 //生成token(使用jwt扩展库)
    function createToken($user=[],$exptime=0)
    {
        $key = md5($this->jwt_secret_key); //jwt的签发密钥,这里的密钥,可以定义在该类的起始位置;
        $time = time(); //签发时间
        $expire = $time + $exptime; //过期时间,作为方法的参数
        $token = array(
            $user,                                //用户信息,作为jwt的信息载体
            "iss" => "ADStudio",//签发组织
            "aud" => "ADONG", //签发作者
            "iat" => $time,
            "nbf" => $time,
            "exp" => $expire
        );
        $jwt = JWTUtil::encode($token,$key);
        return $jwt;
    }  

4.在User数据模型中创建verifyToken方法: 对生成的token进行验证

 //检验token是否合法
function verifyToken($token){
    $key = md5($this->jwt_secret_key); //jwt的签发密钥,验证token的时候需要用到
    try{
        $jwtAuth = json_encode(JWTUtil::decode($token,$key,array("HS256")));
        $authInfo = json_decode($jwtAuth,true);
        return ['msg'=>'token正常','data'=>$authInfo[0]];
    }catch (ExpiredException $e){
        return ['msg'=>'token过期','data'=>[]];
    }catch (\Exception $e){
        return ['msg'=>'token错误','data'=>[]];
    }
}  

5.在用户登录的方法中,添加调用createToken方法,产生token,并且返回到客户端:

 public function nameLogin()
    {
        $params=request()->param();
        $username=$params['username'];
        $userpassword = $params['userpassword'];
        $vcode = $params['vcode'];
         if(!captcha_check($vcode)){
             //调用在通用函数common中的抛出异常错误
             throw_comm_exception('图片验证码错误',10011);
            };
        //使用用户名和密码对数据表进行查询,采用数组方式进行多条件查询
        $arr = ['username'=>$username,
                'userpassword'=>$userpassword
        ];
        //查询
        $usr = User::where($arr)->find();
        //判断返回结果
        if($usr!=NULL){
            //返回正确的数据
            $arr2 = array(
                'name'=>$usr->UserName,
                'admin'=>$usr->UserToAdmin,
                'group'=>$usr->UserToGroup,
                'type'=>$usr->UserType
            );
            $token = $this->createToken($arr2,$this->expire_time);
            return $token;
        }
        else{
            //抛出异常错误信息
            throw_comm_exception('用户名或密码错误',10012);
        }
    }  

6.控制器中用户登录方法(无需更改):

 public function userNameLogin()
    {
        (new UserValidate())->gocheck('userlogin');

        $res = (new UserModel())->nameLogin();
        return $res;
    }  

7.控制器中增加token验证方法(临时增加)

 public function checkToken()
    {
        $token=request()->param('token');
        return json((new UserModel())->verifyToken($token));
    }  

8.在路由中添加两个访问地址(其中第一个用户登录之前已经存在,不用写,第二个是验证token路由,临时测试使用)

     Route::post('user/usernamelogin',':version.user/usernamelogin');
    Route::post('user/checktoken',':version.user/checktoken');  

9.最终测试的效果如下:

通过正常的用户登录,获取基于jwt的token值

对token值进行验证,正确的存放在jwt中的user信息

token错误时的提示信息

token过期时的提示信息

收藏
分享
海报
0 条评论
106
上一篇:PHP 8.1.0 正式发布了 下一篇:PHP学习第十八课:POST与GET,原来这样使用

本站已关闭游客评论,请登录或者注册后再评论吧~

忘记密码?

图形验证码