JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。
廢話就不說了,直接說怎麼實現的
安裝jwt第三方擴展包
composer require lcobucci/jwt
<?php
namespace App\Common;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;
class Jwt {
private static $instance;
private $issue="http://jwt.io/";
private $aud="http://jwt.io/";
private $jti="4f1g23a12aa44";//jwt id
private $key="zq2020";
//設置jwt_token
private $token;
/**
* @var 解析的token
*/
private $decodeToken;
private $uid;
/**
* 設置uid
*/
public function setUid($uid){
$this->uid=$uid;
return $this;
}
/**
* 私有構造方法
*/
public static function getInstance(){
if(is_null(self::$instance)){
self::$instance=new self();
}
return self::$instance;
}
/**
* 私有克隆方法
*/
private function __clone()
{
// TODO: Implement __clone() method.
}
/**
* 獲取jwtToken
*/
public function getToken(){
return (string)$this->token;
}
/**
* 設置token
*/
public function setToken($token){
$this->token=$token;
return $this;
}
/**
* 生成jwt token
*/
public function encode(){
$time = time();
$signer=new Sha256();
$this->token = (new Builder())->issuedBy($this->issue) // Configures the issuer (iss claim)
->permittedFor($this->aud) // Configures the audience (aud claim)
->identifiedBy($this->jti, true) // Configures the id (jti claim), replicating as a header item
->issuedAt($time) // Configures the time that the token was issue (iat claim)
->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim)
->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)
->withClaim('uid', $this->uid) // Configures a new claim, called "uid"
->getToken($signer,new Key($this->key)); // Retrieves the generated token
return $this;
}
/**
* 校驗jwt_token
*/
public function decode(){
if(!$this->decodeToken){
$this->decodeToken=(new Parser())->parse((string)$this->token);
$this->uid=$this->decodeToken->getClaim("uid");//解析出來用戶id
}
return $this->decodeToken;
}
/**
* 校驗jwt_token
*/
public function Validating(){
$data = new ValidationData(time(),30); // It will use the current time to validate (iat, nbf and exp)
$data->setIssuer($this->issue);
$data->setAudience($this->aud);
$data->setId($this->jti);
return $this->decode()->validate($data);
}
/**
* 驗證token
*/
public function verify(){
$result=$this->decode()->verify(new Sha256(),$this->key);
return $result;
}
/**
* 獲取用戶ID
*/
public function getUid(){
return $this->uid;
}
}
這裏控制器的方法是採用了easyswoole這個框架裏面的內置方法
如何使用呢
public function test(){
$jwt_token=Jwt::getInstance()->setUid(1)->encode()->getToken();
return $this->response()->withHeader("token",$jwt_token)->write($jwt_token);
}
如何驗證
public function verity()
{
$token=$this->request()->getRequestParam("token");
if(!$token){
throw new ApiException(ErrorCode::TOKEN_EX);
}
$is_true=Jwt::getInstance()->setToken($token)->Validating();
if(!$is_true){
throw new ApiException(ErrorCode::TOKEN_ERR);
}
$data=[
"code"=>0,
"msg"=>"success"
];
return $this->response()->write(json_encode($data));
}