周大胖子 发表于 2018-11-25 16:15:31

php-jwt的使用

本帖最后由 周大胖子 于 2018-11-28 18:26 编辑

先别拦着哥,哥要哭诉一下:命苦啊,命苦啊!连个老师都没有,又要自学成材, 神啊,我真的想混了除了度娘以外的老师啊!
好了,胖爷逼逼完了,来 开始介绍JWT。
啥玩意是JWT,JWT就是一种取代 session的用户状态储存工具; 牛逼不,劳资自己总结的;
优点:session 什么的太占用服务器内容; jwt 减轻服务器压力,将客户状态分散到了客户端中;
缺点:说起来就是搞笑了,服务器多出了一些计算压力;你得解密啊;

这里有个误区【我是一个session的忠实用户,一般就是在服务器上抽象(想象)出一条储存信息,这个信息包含用户的大体内容;但是jwt就不一样了,他就没有这条信息,他就是张游乐园的门票,你可以携带信息也可以不带。我总觉得这两个有些内容上的相似;】
好了 不 BB了 开始用:
第一步 安装
cd 到项目目录
composer require lcobucci/jwt


第二步,写个生成token的 函数,并且注意 携带的信息

//签发Token
      public function lssue($id,$username)
      {
                $key = 'laomo'; //key
                $time = time(); //当前时间
                     $token = [
                'iss' => '', //签发者 可选
                   'aud' => '', //接收该JWT的一方,可选
                   'iat' => $time, //签发时间
                   'nbf' => $time , //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
                   'exp' => $time+7200, //过期时间,这里设置2个小时
                  'data' => [ //自定义信息,不要定义敏感信息
                           'userid' => $id,
                               'username' => $username
            ]
      ];
      return JWT::encode($token, $key); //输出Token
      }


第三步,使用这个token 函数,当前端请求时还给他个access_tokem 让前端自己存起来以后带入请求头
// 执行登录
    public function dologin(Request $request)
    {
      // 非空验证
      if(!$request->param('username')){
            downjson($code=1,$msg='用户名不能为空');
      }
      if(!$request->param('password')){
            downjson($code=1,$msg='密码不能为空');
      }
      if(!$request->param('vercode')){
            downjson($code=1,$msg='验证码不能为空');
      }

      $dbconfig =[
            'type'=>'mysql',       //数据库类型
            'hostname'=>'106.14.30.64',   //数据库地址
            'username'=>'root',         //数据库用户名
            'password'=>'root',         //数据库密码
            'database'=>'xin07726631'    //数据库名称
      ];
      
      $link = Db::connect($dbconfig);

      $lmb = $link->table('xy_user')->where([
            'name'=>['=',$request->param('username')]
            ,'pwd'=>['=',md5(md5($request->param('password')))]
      ])->find();
      
      //登录用户验证
      if(!$lmb){
            downjson(1,$msg='登录失败,请核对用户名与密码');
      }
      // 在这生成jwt并且返回给前端
      $result=array(
            'code'=> 0
            ,'msg'=> "登录成功"
            ,'data'=> array(
            "access_token" => $this->lssue($lmb['id'],$lmb['username'])
            )
      );
      

      exit( json_encode($result, JSON_UNESCAPED_UNICODE) );

    }

第四步 与前三步不一样,这个地方主要是一个jwt的验证
// // 验证tooken
      public function verification(Request $request)
      {
                $key = 'laomo'; //key要和签发的时候一样

                $jwt =$request->param('access_token'); //签发的Token
      
      try {
            JWT::$leeway = 60;//当前时间减去60,把时间留点余地
            $decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
            $arr = (array)$decoded;
            // return $arr;
            downjson($code=0,$msg='成功','',$data=$arr['data']);
      } catch(\Firebase\JWT\SignatureInvalidException $e) {//签名不正确
            // return $e->getMessage();
            downjson($code=0,$msg=$e->getMessage(),'',$data=$arr);
      }catch(\Firebase\JWT\BeforeValidException $e) {// 签名在某个时间点之后才能用
            // return $e->getMessage();
            downjson($code=0,$msg=$e->getMessage(),'',$data=$arr);
      }catch(\Firebase\JWT\ExpiredException $e) {// token过期
            // return $e->getMessage();
            downjson($code=0,$msg=$e->getMessage(),'',$data=$arr);
      }catch(Exception $e) {//其他错误
            // return $e->getMessage();
            downjson($code=0,$msg=$e->getMessage(),'',$data=$arr);
      }
            //Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
      }



参考文献1:https://blog.csdn.net/cjs5202001/article/details/80228937
参考文献2:https://blog.csdn.net/Drug_/article/details/83995358


页: [1]
查看完整版本: php-jwt的使用