JWT -- thinkphp5.1中的使用

424 阅读1分钟

 话不多说

首先将composer镜像切换到

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

然后在tp5.1根目录运行

composer require lcobucci/jwt 3.2

在application目录下创建common目录 common目录下创建auth目录  创建JwtAuth.php

如下图

​编辑

JwtAuth.php中代码如下

<?php
namespace app\common\auth;

use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Builder;
/**
 * 首先composer
 * composer require lcobucci/jwt:3.2
 * Class JWTAuth
 * 单例模式  一次请求中所有出现使用jwt的地方都是一个用户
 */
class JwtAuth
{
    /**
     * jwt token
     * @var
     */
    private $token;

    /**
     * claim $iss
     * @var string
     */
    private $iss = 'http://localhost/tp5.1/public/index.php';

    /**
     * claim $aud
     * @var string
     */
    private $aud = 'server_app';

    /**
     * claim uid
     * @var
     */
    private $uid;

    /**
     * @var string
     */
    private $secrect = '^&*^*(%(*&^)$^$%&(#%^$&^%$';

    /**
     * decode token
     * @var
     */
    private $decodeToken;


    /**
     * 单例模式  jwtAuth的句柄
     * @var
     */
    private static $instance;


    /**
     * 获取jwtAuth的句柄
     * @return JWTAuth
     */
    public static function getInstance()
    {
        if(is_null(self::$instance))
        {
            self::$instance = new self();

        }

        return self::$instance;
    }

    /**
     * 私有化构造函数
     * JWTAuth constructor.
     */
    private function __construct()
    {

    }

    /**
     * 私有化clone函数
     */
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 获取token
     * @return string
     */
    public function getToken()
    {
        return (string)$this->token;
    }

    /**
     * 设置token
     * @param $token
     * @return $this
     */
    public function setToken($token)
    {
        $this->token = $token;

        return $this;
    }

    /**
     * 设置uid
     * @param $uid
     * @return $this
     */
    public function setUid($uid)
    {
        $this->uid = $uid;
        return $this;
    }

    public function getUid(){
        return $this->uid;
    }

    /**
     * 编码JWT token
     * @return $this
     */
    public function encode()
    {
        $time = time();

        $this->token = (new Builder())->setHeader('alg','HS356')
            ->setIssuer($this->iss)
            ->setAudience($this->aud)
            ->setIssuedAt($time)
            ->setExpiration($time + 3600)
            ->set('uid',$this->uid)
            ->sign(new Sha256(),$this->secrect)
            ->getToken();


        return $this;

    }

    /**
     * parse decode token
     * @return \Lcobucci\JWT\Token
     */
    public function decode()
    {
        if(!$this->decodeToken) {
            $this->decodeToken = (new Parser())->parse((string)$this->token);
            $this->uid = $this->decodeToken->getClaim('uid');
        }

        return $this->decodeToken;
    }

    /**
     * verify  验证token
     */
    public function verify()
    {
        $result = $this->decode()->verify(new Sha256(),$this->secrect);

        return $result;
    }

    /**
     * validate
     * @return bool
     */
    public function validate()
    {
        $data = new ValidationData();
        $data->setIssuer($this->iss);
        $data->setAudience($this->aud);

        return $this->decode()->validate($data);
    }


}

创建一个控制器 代码如下

<?php
namespace app\index\controller\v1;

use app\common\auth\JwtAuth;
use app\response\ResponseJson;
use think\Controller;

class Register extends Controller
{
    use ResponseJson;
    #控制器中间件的使用
    protected $middleware = [
        //except是除了数组中的方法不走中间件 only是只有数组中的方法走中间件
        'JwtCheck' => ['only'=>['index']]  
        
    ];

    public function registerDo()
    {
        $jwtAuth = JwtAuth::getInstance();
        $token = $jwtAuth->setUid(1)->encode()->getToken();

        return $this->jsonSuccessData(['token'=>$token]);
    }

    public function index()
    {
        echo 'index';
    }

 使用中间件验证Jwt 

创建中间件 在项目根目录运行

php think make:middleware Check

之后会生成 如下图   Check的名字可以改

​编辑

在app目录下生成了http\middleware\JwtCheck.php    JwtCheck.php中代码如下

<?php
namespace app\http\middleware;

use app\common\auth\JwtAuth;
use app\response\ResponseJson;

class JwtCheck
{
    use ResponseJson;
    public function handle($request, \Closure $next)
    {
        #获取header中的token
        $token = $request->header('token');
        if($token)
        {
            $jwtAuth = JwtAuth::getInstance();
            $jwtAuth->setToken($token);
            if($jwtAuth->validate() && $jwtAuth->verify())
            {
                return $next($request);
            }else{
                return json(['code'=>1,'msg'=>'TOKEN ERROR','data'=>[]]);
            }
        }else{
            return json(['code'=>1,'msg'=>'ERROR','data'=>[]]);
        }
    }
}

Jwt就可以正常使用了