一 通过Composer安装firebase/php-jwt 5.2.1版本
composer require firebase/php-jwt 版本号
二 common.php公共函数文件
use Firebase\JWT\JWT; //引入JWT
/**
* @param $data
* @return string
* 生成token
*/
function setToken($data)
{
$key = 'key'; //秘钥:自定义
$payload = array(
'iss' => '', //签发人(官方字段:非必需)
'aud' => '', //受众(官方字段:非必需)
'iat' => time(), //签发时间
'nbf' => time(), //生效时间
'exp' => time() + 3600, //过期时间
'uid' => $data //自定义字段
);
//加密生成token
$jwt = JWT::encode($payload, $key);
return $jwt;
}
/**
* @param $token
* @return mixed
* 解析token
*/
function chekToken()
{
try {
$key = 'key';
JWT::$leeway = 60;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($header['token'], $key, array('HS256')); //HS256方式,这里要和签发的时候对应
$this->uid = $decoded->uid;
} catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
echo $e->getMessage();
exit();
} catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
echo $e->getMessage();
exit();
} catch (\Firebase\JWT\ExpiredException $e) { // token过期
echo $e->getMessage();
exit();
} catch (\Exception $e) { //其他错误
echo $e->getMessage();
exit();
}
}
- 封装单例模式
<?php
/**
* Created by PhpStorm.
* User: EDZ
* Date: 2019/8/28
* Time: 12:41
*/
namespace app\common\Auth;
use Firebase\JWT\JWT;
class JwtAuth
{
// 秘钥
private $key = 'defined-202002022020-xxxxx-key';
// 发行人
private $iss = 'www.test.com';
// 受众
private $aud = 'www';
// 登录id
private $uid;
// 权限
private $role;
// 加密token
private $token;
// 解密token
private $decodeToken;
// 单例
private static $instance;
/**
* 单例模式
* @return JwtAuth
*/
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 私有化构造函数
* JwtAuth constructor.
*/
private function __construct()
{
}
/**
* 私有化克隆函数
*/
private function __clone()
{
// TODO: Implement __clone() method.
}
// 获取uid
public function getUid()
{
return $this->uid;
}
// 设置uid
public function setUid($uid)
{
$this->uid = $uid;
return $this;
}
// 获取role
public function getRole()
{
return $this->role;
}
// 设置role
public function setRole($role)
{
$this->role = $role;
return $this;
}
// 设置token
public function setToken($token)
{
$this->token = $token;
return $this;
}
// 获取token
public function getToken()
{
return (string)$this->token;
}
/**
* 加密token
* @return $this
*/
public function encode()
{
$time = time();
$params = [
'iss' => $this->iss,
'aud' => $this->aud,
'iat' => $time, // 签发时间
'nbf' => $time + 10, // 该时间段不允许操作token
'exp' => $time + 3600 * 24 * 7, // 过期时间7天
'uid' => $this->uid,//uid
'role' => $this->role,//role
];
$this->token = JWT::encode($params, $this->key, "HS256");
return $this;
}
/**
* 解密token
* @param $jwt
* @return array
*/
public function decode($jwt)
{
JWT::$leeway = 60;
$decoded = JWT::decode($jwt, $this->key, ["HS256"]);
$this->decodeToken = (array)$decoded;
$this->uid = $this->decodeToken['uid'];
$this->role = $this->decodeToken['role'];
return $this->decodeToken;
}
}
- 登录调用
$jwt = JwtAuth::getInstance();
$token = $jwt->setUid($uid)->setRole($role)->encode()->getToken();//获取token
- 路由中间件拦截验证token
public function handle($request, \Closure $next)
{
$token = $request->param('token');
if ($token) {
$jwt = JwtAuth::getInstance();
$decodeToken = $jwt->decode($token);
if (!$decodeToken) {
throw new BaseExecption(ApiErrorDesc::ERR_TOKEN);
}
if ($decodeToken['exp'] < time()) {
throw new BaseExecption(ApiErrorDesc::ERR_LOGIN_EXPIRE);
}
return $next($request);
} else {
throw new BaseExecption(ApiErrorDesc::ERR_PARAMS);
}
}
- Base公共控制器获取用户信息以及权限避免重复查询数据库
<?php
/**
* Created by PhpStorm.
* User: EDZ
* Date: 2019/9/2
* Time: 11:33
*/
namespace app\index\controller;
use app\index\common\Auth\JwtAuth;
use think\Controller;
header("Access-Control-Allow-Credentials:true");
header('Access-Control-Allow-Origin:*');
class Base extends Controller
{
protected $uid;
protected $role;
public function __construct()
{
$token = input('token');
$jwt = JwtAuth::getInstance();
$this->uid = $jwt->setToken($token)->getUid();
$this->role = $jwt->setToken($token)->getRole();
parent::__construct();
}
}
- 单例模式
class JwtAuth
{
// 秘钥
const KEY = 'defined-202002022020-testkeyauto-key';
// 发行人
const ISS = 'quality.test.com';
// 受众
const AUD = 'quality';
// 登录id
private $uid;
// 权限
private $role;
// 加密token
private $token;
// 解密token
private $decodedToken;
// 单例
private static $instance;
/**
* 私有化构造函数
*/
private function __construct()
{
$this->uid = null;
$this->role = null;
}
/**
* 单例模式
* @return JwtAuth
*/
public static function getInstance()
{
if (!isset(self::$instance) || is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 私有化克隆函数
*/
private function __clone()
{
// TODO: Implement __clone() method.
}
/**
* 设置登录 id 和权限
* @param $uid
* @param $role
* @return $this
*/
public function setAuth($uid, $role)
{
$this->uid = $uid;
$this->role = $role;
return $this;
}
/**
* 加密token
* @param array $payload JWT 配置项
* @return $this
*/
public function encode(array $payload = [])
{
$params = array_merge([
'iss' => self::ISS,
'aud' => self::AUD,
'nbf' => time() + 10, // 该时间段不允许操作token
'exp' => time() + 3600 * 24 * 7, // 过期时间
'uid' => $this->uid,
'role' => $this->role
], $payload);
$this->token = JWT::encode($params, self::KEY, "HS256");
return $this;
}
/**
* 解密token
* @param string $jwt 待解密的 token
* @return array
*/
public function decode(string $jwt)
{
try {
$decoded = JWT::decode($jwt, self::KEY, array("HS256"));
$this->decodedToken = (array)$decoded;
return $this->decodedToken;
} catch (Firebase\JWT\ExpiredException | Firebase\JWT\SignatureInvalidException $e) {
// Log or handle the error as appropriate
return false;
}
}
/**
* 获取解密后的 uid
* @return int|null
*/
public function getUid()
{
if (isset($this->decodedToken['uid'])) {
return $this->decodedToken['uid'];
} else {
return null;
}
}
/**
* 获取解密后的权限
* @return string|null
*/
public function getRole()
{
if (isset($this->decodedToken['role'])) {
return $this->decodedToken['role'];
} else {
return null;
}
}
/**
* 获取加密后的 token
* @return string|null
*/
public function getToken()
{
return $this->token;
}
}