JWT(JSON WEB TOKEN)是一种无状态的token机制,可以用来进行前后端交互的用户认证,或者接口鉴权。
主要优势
- 无状态
加密解密过程无需操作数据库或者缓存,是一个无状态的过程,执行效率高,而且可以在不同系统中传递,实现单点登录功能(需要各个系统的key一致)。
-
主要缺点
- 登录状态续签
token有效期即将到期后无法自动续签,可以前端处理获取到的token有效期快过的时候再请求一个新的token,不过也无法保障永续。
- 旧的token无法注销
获取到新的token后,只要旧的token没有过期,还可以继续使用。解决办法有用户注销时把旧的token加黑名单等,但是这样就破坏了它本身无状态的优势,每次验证都要访问缓存。
token组成
header.payload.sign
-
header中包含了加密算法等信息,payload包含有效载荷信息,sign是签名;
-
payload一般需要包含expired_time、refresh_time等信息,还有自定义的信息
-
加密解密算法可用的封装:composer require firebase/php-jwt
token验证逻辑实现:
<?php
namespace App\Http\Middleware;
use Closure;
use Firebase\JWT\JWT;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
/**
* jwt验证中间件
* Class CheckJwtToken
* @package App\Http\Middleware
*/
class CheckJwtToken
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
if (!$token) {
throw new UnauthorizedHttpException('','JWT TOKEN AUTH FAILED');
}
$payload = JWT::decode($token, getenv('JWT_SECRET'), ['HS256']);
if (isset($payload->expired_at) && $payload->expired_at < time()) {
throw new UnauthorizedHttpException('','JWT TOKEN AUTH FAILED');
}
//验证通过,可以使用payload中的信息了
......
}
}
如果需要refresh的功能,可以参考这篇文章:
网友评论