在使用laravel时候 摒弃了自带的Auth和passport。主要原因是项目前后端分离,后端写api接口,另外email不做登录选项,password和用户信息存储分开存。在使用JWT过程中遇到很多的坑。
坑1 不能用JWTAuth静态调用
直接
public function xxx (JWTAuth $jwt){
$jwt->xxx;
}
这里的JWTAuth是
use Tymon\JWTAuth\JWTAuth;
感兴趣的可以看看 JWT.php 和JWTAuth.php这两个文件
坑2 token过期自动刷新
token有两个有效期,在config/jwt.php下面
'ttl' => env('JWT_TTL', 60),
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
这假设用户登录,半个月内登录有效,那么这里的半个月是refresh_ttl,ttl是什么呢?ttl是单个签发的token有效期。
你半个月内可以有n个token,毕竟1个小时就过期,这时候过期不是真正过期,可以进行签发新token。
看了很多文档,大体上就写了个refresh token的接口
其实JWT在处理时候,如果token过期,你没有进行try catch处理,这里会报错的。而且前端没有获取到新token需要存储。
public function tokenValidator(&$request,$jwt){
#检测request中header头是否带了token
if(is_null($token = \request() ->header('authorization'))){
$this->response(400,'Authorization Failed,未携带Authorization');
}
#提取token中用户数据
try{
$user = $jwt->parseToken()->toUser()->toArray();
if(! $user){
$this->response(200,'用户不存在','');
}
}catch (TokenExpiredException $exception){
#异常处理 token过有效期,进行刷新
try{
$token = $jwt->refresh();
$access_token = 'Bearer'.$token;
$request->headers->set('Authorization',$access_token);
}catch(JWTException $exception){
#refresh 也过期,重新登录
$this->response(400,'Authorization过期,重新登录');
}
}
}
token如果过期,通过TokenExpiredException 可以catch到异常然后进行刷新token,刷新token又不能这时候response给前端,因为你用户登录有效期没过,这个接口得继续往下走,那么在request header头里加上这个token,后面接口使用时候就是新token,但是后面接口在返回时候又要带上新token给前端,让前端进行存储。
总觉得自己写的代码号low