周大胖子 发表于 2018-12-24 11:02:37

TP5.0 中如何使用jwt

login.php    在这个操作时,签发jwt;并且携带基础信息
<?php
namespace app\index\controller;
use think\Request;
use think\Db;
use app\index\model\Admins;

// 引入jwt
use \Firebase\JWT\JWT;

class Login
{
   
    public function index()
    {
      return '<style type="text/css">*{ padding: 0; margin: 0; } .think_default_text{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:)</h1><p> ThinkPHP V5<br/><span style="font-size:30px">十年磨一剑 - 为API开发设计的高性能框架</span></p><span style="font-size:22px;">[ V5.0 版本由 <a href="http://www.qiniu.com" target="qiniu">七牛云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ad_bd568ce7058a1091"></think>    }
    public function mv()
    {
      return '我进来了    }

    // 执行登录
    public function dologin(Request $request)
    {
      if (Request::instance()->isOptions()){
            die;
      }
      // 非空验证
      if(!$request->param('username')){
            downjson($code=1,$msg='用户名不能为空');
      }
      if(!$request->param('password')){
            downjson($code=1,$msg='密码不能为空');
      }
      if(!$request->param('vercode')){
            downjson($code=1,$msg='验证码不能为空');
      }
      $ip = Request::instance()->ip();

      // 只根据用户名拿数据
      $where = function ($query) use($request){
            $query->where([
                  'username' =>['=',$request->param('username')],
                ]);
      };
      //在这有个坑点 返回值 只能是数组、字符串、不能反回一个对象
      $lmb = Admins::get($where);
      
      //登录用户验证
      if(!$lmb){
            downjson(1,'登录失败,该用户不存在');
      }
      // 登录用户密码验证
      if( MD5($request->param('password')) !== $lmb->getData()['password'] ){
            downjson(1,'登录失败,密码错误');
      }
      // 判断该用户是否被禁用
      if($lmb->getData()['status']!==1){
            downjson(1,'该用户已被管理员禁用');
      }
      // 在这生成jwt并且返回给前端
      $result=array(
            'code'=> 0
            ,'msg'=> "登录成功"
            ,'data'=> array(
            "access_token" => $this->lssue($lmb['id'],$lmb['truename'],$ip)
            )
      );

      exit( json_encode($result, JSON_UNESCAPED_UNICODE) );

    }

    // 用户信息 通过解析access_token 获得
    public function userInfo(Request $request)
    {
      // 判断是不是option请求
      if (Request::instance()->isOptions()){
            die;
      }
      $key = 'laomo'; //key要和签发的时候一样
      $info = Request::instance()->header(); //直接在这里放'access_token' 居然接收不到值

      if(isset($info['access_token'])){
            $jwt = $info['access_token'];
      }else{
            $jwt = input('access_token');
      }

      if(empty($jwt)){
            downjson($code=161,$msg='请登录',$info['access_token']);
      }

      try {
            JWT::$leeway = 60;//当前时间减去60,把时间留点余地
            $decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
            $arr = (array)$decoded;
            downjson($code=0,$msg='成功','',$data=$arr['data']);
      } catch(\Firebase\JWT\SignatureInvalidException $e) {//签名不正确
            // return $e->getMessage();
            downjson($code=161,$msg=$e->getMessage());
      }catch(\Firebase\JWT\BeforeValidException $e) {// 签名在某个时间点之后才能用
            // return $e->getMessage();
            downjson($code=161,$msg=$e->getMessage());
      }catch(\Firebase\JWT\ExpiredException $e) {// token过期
            downjson($code=162,$msg=$e->getMessage());
      }catch(Exception $e) {//其他错误
            downjson($code=162,$msg=$e->getMessage());
      }
    }

   //签发Token
        public function lssue($id,$username,$ip)
        {
                $key = 'laomo'; //key
                $time = time(); //当前时间
                       $token = [
              'iss' => '', //签发者 可选
                 'aud' => $ip, //接收该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
        }

      
}




基类 Base.php验证jwt 获取对应信息;
<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use \Firebase\JWT\JWT; //导入JWT
use think\auth\Auth;

class Base extends Controller
{
    public $useinfo = array(); //存储用户信息
    // 登录验证
    public function _initialize()
    {
      // 判断是不是option请求
      if (Request::instance()->isOptions()){
            die;
      }
      $key = 'laomo'; //key要和签发的时候一样
      $info = Request::instance()->header(); //直接在这里放'access_token' 居然接收不到值

      if(isset($info['access_token'])){
            $jwt = $info['access_token'];
      }else{
            $jwt = input('access_token');
      }
      
      if(empty($jwt)){
            downjson($code=161,$msg='请登录');
      }

      try {
            JWT::$leeway = 60;//当前时间减去60,把时间留点余地
            $decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
            $arr = (array)$decoded;
            $this->useinfo = $arr['data']; //提出存储在jwt的用户信息
      } catch(\Firebase\JWT\SignatureInvalidException $e) {//签名不正确
            downjson($code=161,$msg=$e->getMessage());
      }catch(\Firebase\JWT\BeforeValidException $e) {// 签名在某个时间点之后才能用
            downjson($code=161,$msg=$e->getMessage());
      }catch(\Firebase\JWT\ExpiredException $e) {// token过期
            downjson($code=162,'登陆超时');
      }catch(Exception $e) {//其他错误
            downjson($code=162,$msg=$e->getMessage());
      }


    }

   
}



页: [1]
查看完整版本: TP5.0 中如何使用jwt