1.安装依赖
composer require firebase/php-jwt
2.配置jwt。 路径 config/autoload/jwt.php
<?php
declare(strict_types=1);
return [
'key' => 'qewwqeqweqweqweqw',
'issue' => 'qqqqq',
'expire' => 7200
];
3.对jwt的封装
<?php
declare(strict_types=1);
namespace App\Service;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
class JWTService
{
public function encode($data)
{
$time = time();
$key = config('jwt.key');
$issue = config('jwt.issue');
$expire = config('jwt.expire');
$payload = array(
'iss' => $issue,
'iat' => $time,
'nbf' => $time,
'exp' => $time + $expire,
'data' => $data
);
return JWT::encode($payload, $key);
}
public function decode($token)
{
$key = config('jwt.key');
try {
JWT::$leeway = 120;//当前时间减去60,把时间留点余地
$decoded = JWT::decode($token, $key, ['']); //HS256是默认方式,`在这里插入代码片`这里要和签发的时候对应
$arr = (array)$decoded;
return (array)$arr['data'];
} catch (SignatureInvalidException $e) { //签名不正确
return false;
} catch (BeforeValidException $e) { // 签名在某个时间点之后才能用
return false;
} catch (ExpiredException $e) { // token过期
return false;
}
}
}
4.权限验证中间件
<?php
declare(strict_types=1);
namespace App\Middleware;
use App\Service\JWTService;
use App\Service\UserService;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Utils\Context;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class JwtMiddleware implements MiddlewareInterface
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var JWTService
*/
protected $jwtService;
/**
* @var UserService
*/
protected $userService;
public function __construct(ContainerInterface $container,JWTService $jwtService,UserService $userService)
{
$this->container = $container;
$this->jwtService = $jwtService;
$this->userService = $userService;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = Context::get(ResponseInterface::class);
$path = $request->getUri()->getPath();
$arrPath = explode('/',$path);
if(is_numeric(end($arrPath))){
array_pop($arrPath);
$path = implode('/',$arrPath);
}
$ignorePath = config('ignore_path');
//验证token
if(!in_array($path,$ignorePath )){
$hasToken = $request->hasHeader('Authorization');
$token = $request->getHeaderLine('Authorization');
if(!$hasToken || empty($token)){
$data = json_encode([
'code' => 402,
'message' => '请重新登录'
],JSON_UNESCAPED_UNICODE);
return $response->withStatus(200)->withBody(new SwooleStream($data));
}
try{
$arr = $this->jwtService->decode($token);
}catch (\Exception $exception){
$data = json_encode([
'code' => 402,
'message' => '登录凭证异常,请重新登录'
],JSON_UNESCAPED_UNICODE);
return $response->withStatus(200)->withBody(new SwooleStream($data));
}
$userId = (int)$arr['userId'] ?? 0;
$userInfo = $this->userService->getUserInfo($userId);
if(empty($userInfo)){
$data = json_encode([
'code' => 402,
'message' => '登录凭证异常,请重新登录',
],JSON_UNESCAPED_UNICODE);
return $response->withStatus(200)->withBody(new SwooleStream($data));
}
$request = $request->withAttribute('userInfo',$userInfo);
$request = Context::set(ServerRequestInterface::class,$request);
}
return $handler->handle($request);
}
}
5.在配置文章config/autoload/middlewares中添加权限中间件
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'http' => [
\App\Middleware\JwtMiddleware::class,
],
];