Yii 使用JWT

瞭解JWT能夠參考:瞭解JWTphp

一:下載JWT拓展前端

在JWT官網中咱們能夠看到不少php版本的JWT,選擇一個JWT進行下載算法

clipboard.png

這裏我選擇的是lcobucci/jwt,使用composer進行下載app

lcobucci/jwt的composer地址:https://packagist.org/package...composer

composer require lcobucci/jwt "^3.3.0"  #這裏我下載的是3.3.0版本

二:lcobucci/jwt使用dom

lcobucci/jwt使用方法能夠參考下載下來的README.md文件(vendor/lcobucci/jwt/README.md)yii

1:生成JWTide

$request = Yii::$app->getRequest();
$signer = new Sha256();//使用Sha256加密,經常使用加密方式有Sha256,Sha384,Sha512
$time = time();
$tokenBuilder = (new Builder())
    ->issuedBy($request->getHostInfo()) // 設置發行人
    ->permittedFor(isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '') // 設置接收
    ->identifiedBy(Yii::$app->security->generateRandomString(10), true) // 設置id
    ->issuedAt($time) // 設置生成token的時間
    ->canOnlyBeUsedAfter($time) // 設置token使用時間(實時使用)
    ->expiresAt($time + 3600); //設置token過時時間
//定義本身所需字段
$user = ['user_name' => '測試', 'user_no' => '001'];
$tokenBuilder->withClaim('user', $user);
$tokenBuilder->withClaim('ceshi', '測試字段');
//使用Sha256加密生成token對象,該對象的字符串形式爲一個JWT字符串
$token = $tokenBuilder->getToken($signer, new Key('jwt_secret'));
echo (string) $token;

2:對JWT進行校驗測試

在正常的開發環境下,咱們將生成的JWT字符串傳到前端,當前端調用其餘接口時,將咱們所給的JWT傳遞到後臺,咱們後臺須要對前端傳來的JWT字符串進行校驗ui

下面的$token爲咱們獲取到的前端傳遞的JWT

$token = (new Parser())->parse($token);
//數據校驗
$data = new ValidationData(); // 使用當前時間來校驗數據
if (!$token->validate($data)) {
    //數據校驗失敗
    return '數據校驗失敗';
}
//token校驗
$signer = new Sha256();//生成JWT時使用的加密方式
if (!$token->verify($signer, new Key('jwt_secret'))) {
    //token校驗失敗
    return 'token校驗失敗';
}
echo '校驗成功';

3:獲取JWT的相關信息

$token = (new Parser())->parse($token);
$token->getHeaders(); // 獲取JWT的Header(頭部)信息
$token->getClaims(); // 獲取JWT的PayLoad(負載)信息
//獲取指定參數的PayLoad(負載)信息
$token->getClaim('jti');
$token->getClaim('user');

三:編寫一個JWT類,方便對於JWT的使用

1:建立一個JWT類,代碼以下:

<?php
/**
 * author: wangjian
 * date: 2019/6/24
 */
namespace app\components;

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Claim\Factory as ClaimFactory;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Parsing\Decoder;
use Lcobucci\JWT\Parsing\Encoder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Token;
use Lcobucci\JWT\ValidationData;
use Yii;
use yii\base\Component;
use yii\base\InvalidParamException;

/**
 * JWT 通用方法
 * Class JWT
 * @package app\components
 */
class JWT extends Component
{

    /**
     * @var array 支持的加密算法
     */
    public $supportedAlgs = [
        'HS256' => 'Lcobucci\JWT\Signer\Hmac\Sha256',
        'HS384' => 'Lcobucci\JWT\Signer\Hmac\Sha384',
        'HS512' => 'Lcobucci\JWT\Signer\Hmac\Sha512',
    ];
    
    /**
     * 實例化JWT生成器
     * @see [[Lcobucci\JWT\Builder::__construct()]]
     * @return Builder
     */
    public function getBuilder(Encoder $encoder = null, ClaimFactory $claimFactory = null)
    {
        return new Builder($encoder, $claimFactory);
    }
    
    /**
     * 實例化JWT分析器
     * @see [[Lcobucci\JWT\Parser::__construct()]]
     * @return Parser
     */
    public function getParser(Decoder $decoder = null, ClaimFactory $claimFactory = null)
    {
        return new Parser($decoder, $claimFactory);
    }
    
    /**
     * 驗證JWT並返回一個令牌類
     * function: ValiJwt
     * @return Token|null
     */
    public function ValiJwt($token, $validate = true, $verify = true)
    {
        try {
            $token = $this->getParser()->parse((string)$token);
        } catch (\RuntimeException $e) {
            // Yii::warning("Invalid JWT provided: " . $e->getMessage(), 'jwt');
            return null;
        } catch (\InvalidArgumentException $e) {
            // Yii::warning("Invalid JWT provided: " . $e->getMessage(), 'jwt');
            return null;
        }
        if ($validate && !$this->validateToken($token)) {
            return null;
        }
        if ($verify && !$this->verifyToken($token)) {
            return null;
        }
        return $token;
    }
    
    /**
     * 數據驗證
     * Validate token
     * @param Token $token token object
     * @return bool
     */
    public function validateToken(Token $token, $currentTime = null)
    {
        $data = new ValidationData($currentTime);
        // @todo Add claims for validation
        return $token->validate($data);
    }
    
    /**
     * Validate token
     * @param Token $token token object
     * @return bool
     */
    public function verifyToken(Token $token)
    {
        $alg = $token->getHeader('alg');
        if (empty($this->supportedAlgs[$alg])) {
            throw new InvalidParamException('Algorithm not supported');
        }
        $signer = Yii::createObject($this->supportedAlgs[$alg]);
        return $token->verify($signer, new Key('jwt_secret'));
    }
    
}

2:在配置文件中添加(引入JWT類):

'components' => [
...
'jwt' => [
            'class' => 'app\components\Jwt'
        ],
...
]

3:使用:

Yii::$app->jwt
Yii::$app->jwt->getBuilder() #等同於new Builder() 
Yii::$app->jwt->ValiJwt($token);JWT驗證
相關文章
相關標籤/搜索