安装jwt
composer require lcobucci/jwt 4.0
在应用目录下新建middleware文件夹,新建JwtBaseService.php
代码如下
<?php
namespace app\api\middleware;
use Illuminate\Support\Facades\Date;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
/**
* 单例 一次请求中所有出现jwt的地方都是一个用户
* Class JwtAuth
* @package app\api\middleware
*/
class JwtBaseService
{
private $config;
private $key = "Ge1KCTRhdVsmUUZY0GrwgEvLubPvLOCM";
private $iss = "www.bugquit.com";//颁发者(iss声明)
private $aud = "www.bugquit.com";//访问群体(aud声明)
private $jti = "secondar"; //id(jti声明)
private $iat = "secondar"; //id(jti声明)
private $expTime = 1;//令牌有效时间,单位小时
private static $instance;// 单例模式JwtAuth句柄
// 获取JwtAuth的句柄
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 构造初始化配置
* JwtToken constructor.
*/
public function __construct()
{
self::init();
}
public function setKey(string $key)
{
$this->key = $key;
self::init();
}
private function init()
{
$config = Configuration::forSymmetricSigner(
new Sha256(),
InMemory::base64Encoded($this->key)
);
$this->config = $config;
}
/**
* 创建JWT
* @param array $arrClaim
* @return string
* @throws \think\Exception
* @author 一颗大萝北 [email protected]
*/
public function createToken(array $arrClaim)
{
$config = $this->config;
assert($config instanceof Configuration);
if (count($arrClaim) == count($arrClaim, 1)) {
exception("claim参数必须为二维数组");
}
$now = new \DateTimeImmutable();
$token = $config->builder()
// 配置颁发者(iss声明)
->issuedBy($this->iss)
// 配置访问群体(aud声明)
->permittedFor($this->aud)
// 配置id(jti声明)
->identifiedBy($this->jti)
// 配置令牌发出的时间(iat声明)
->issuedAt($now)
// 配置令牌的过期时间(exp claim)
->expiresAt($now->modify("+{$this->expTime} hour"));
//写入claim
foreach ($arrClaim as $k => $item) {
$token = $token->withClaim($k, $item);
}
// 生成新令牌
$token = $token->getToken($config->signer(), $config->signingKey());
return $token->toString();
}
/**
* 解析token
* @param string $jwt
* @return mixed
* @author 一颗大萝北 [email protected]
*/
public function parseToken(string $jwt)
{
$config = $this->config;
$token = $config->parser()->parse($jwt);
return $token->claims();
}
/**
* 验证令牌
* @param $jwt
* @return mixed
* @throws \think\Exception
* @author 一颗大萝北 [email protected]
*/
public function validatorToken($jwt)
{
$config = $this->config;
$token = $config->parser()->parse($jwt);
$claims = $token->claims();
$jti = (string)$claims->get('jti');
$iss = (string)$claims->get('iss');
$aud = $claims->get('aud');
$exp = $claims->get('exp');
$now = new \DateTimeImmutable();
// 是否过期
if ($exp < $now) {
exception("身份已过期");
}
//验证jwt id是否匹配
$validate_jwt_id = new \Lcobucci\JWT\Validation\Constraint\IdentifiedBy($jti);
// 验证签发人url是否正确
$validate_issued = new \Lcobucci\JWT\Validation\Constraint\IssuedBy($iss);
// 验证客户端url是否匹配
$validate_aud = new \Lcobucci\JWT\Validation\Constraint\PermittedFor($aud[0]);
$config->setValidationConstraints($validate_jwt_id, $validate_issued, $validate_aud);
$constraints = $config->validationConstraints();
//验证方法2
if (!$config->validator()->validate($token, ...$constraints)) {
exception("非法的请求");
}
return $claims;
}
}
新建中间件文件夹middleware,新建中间件文件ApiMiddleware.php
<?php
/**
* +———————————————————————-
* | Api中间件
* +———————————————————————-
*/
namespace app\api\middleware;
use think\facade\Request;
use think\Response;
use think\exception\HttpResponseException;
class ApiMiddleware
{
public function handle($request, \Closure $next)
{
$strToken = Request::header('X-Token');
if ($strToken) {
if (count(explode('.', $strToken)) <> 3) {
exception('非法身份信息,请重新登录', -1);
}
//获取JwtAuth的句柄
$objJwtAuth = JwtBaseService::getInstance();
$claims = $objJwtAuth->validatorToken($strToken);
$request->claims = $claims;
return $next($request);
} else {
exception('请先登录', -1);
}
}
}
在api接口文件中使用即可
如在user.php中使用,这里lanr不需要鉴权
protected $middleware = [
‘app\api\middleware\ApiMiddleware’ => [‘except’ => [‘lanr’]],
];
如果都需要鉴权那就
'app\api\middleware\ApiMiddleware' => ['except' => []],
签发
JwtBaseService::getInstance()->createToken(['uid' => '11111']);
方法中使用
halt(Request()->claims->get('uid'));
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
一颗大萝北
本文地址: TP6使用lcobucci/jwt 4.0开发接口,用于token和鉴权
本文地址: TP6使用lcobucci/jwt 4.0开发接口,用于token和鉴权