JWTRoleAuth.php
8.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
* 中间件:验证登录JWT token
+-----------------------------------------------------------------------------------------------------------------------
*
* @copyright Copyright
* @author Richer
* @package App\Http\Middleware
* @version 2019年10月9日,14:22:14
* @link
* @since 2019-10-09
*/
namespace App\Http\Middleware;
use App\Models\User\User;
use Closure;
use JWTAuth;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class JWTRoleAuth extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 检查此次请求中是否带有 token,如果没有则抛出异常。
// $this->checkForToken($request);
//
// // 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常
// try {
// // 检测用户的登录状态,如果正常则通过
// if ($this->auth->parseToken()->authenticate()) {
// return $next($request);
// }
// throw new UnauthorizedHttpException('jwt-auth', '未登录');
// } catch (TokenExpiredException $exception) {
// // 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
// try {
// // 刷新用户的 token
// $token = $this->auth->refresh();
// // 使用一次性登录以保证此次请求的成功
// Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
// } catch (JWTException $exception) {
// // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
// throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
// }
// }
//
// // 在响应头中返回新的 token
// return $this->setAuthenticationHeader($next($request), $token);
// 检测request中header头是否带了token
//
try {
$this->checkForToken($request);
} catch (UnauthorizedHttpException $e) {
//Log::info('令牌没有提供');
//获取到用户数据,并赋值给$user
return response()->json([
'code' => 3001,
'msg' => '请登录!', //token无效
'data' => null,//$e->getMessage(),
'token' => '',
]);
}
// 提取token中用户数据
try {
// 通过令牌验证用户。
// $user = $this->auth->parseToken()->authenticate();
$user = $this->auth->parseToken()->getClaim('role');
if (!$user) {
//获取到用户数据,并赋值给$user
return response()->json([
'code' => 3002,
'msg' => '未查询到该用户信息,请登录!', //token无效
'data' => null,
'token' => '',
]);
}
// add by Richer 于 2021年6月16日11:19:49 获取用户的角色,根据角色来判断不同的用户表
$role = optional($user)->role;
dd($user);
dump($role);
// 如果获取用户信息正常,需要判断是否该用户是否存在,并且是否被禁用
if (!$user = User::find($user->id)) {
return response()->json([
'code' => 3002,
'msg' => '未查询到该用户信息,请登录!',
'data' => '',
'token' => '',
]);
}
// 并且是否被禁用
if ($user->status == User::DISABLE) {
return response()->json([
'code' => 3002,
'msg' => '该用户已被禁用,请联系管理员!',
'data' => null,
'token' => '',
]);
}
// TODO 如果获取用户信息正常,需要判断是否是刷新了token ,控制只能在一个设备上进行登录
// $token = $this->auth->parseToken()->getToken();
// if ($user->token != $token) {
// return response()->json([
// 'code' => 3002,
// 'msg' => '该用户已在其他设备登录,请重新登录!',
// 'data' => null,
// 'token' => '',
// ]);
// }
// add by Richer 于 2020年4月27日14:19:09 将用户信息也放在请求中,双保险
$request->user = $user;
} catch (TokenExpiredException $e) {
// token 过期的情况
try {
//首先获得过期token 接着刷新token 再接着设置token并且验证token合法性
$token = JWTAuth::refresh(JWTAuth::getToken());
JWTAuth::setToken($token);
$user = JWTAuth::authenticate($token);
// Save user 刷新令牌,并将令牌重新入库
if ($user) {
$user->token = $token;
$user->save();
// token被刷新之后,保证本次请求在controller中需要根据token调取登录用户信息能够执行成功
$request->user = $user;
// 将token放在请求中,继续执行,最后将token返回到客户端,做到无痛刷新
$request->token = $token;
$request->headers->set('Authorization', 'Bearer '.$token); //
}
//Log::info(json_encode($request));
// 继续
return $next($request);
//Log::info('令牌已过期,重新刷新,并继续执行');
// 首先获得过期token 接着刷新token 再接着设置token并且验证token合法性
// Refresh an expired token.
$token = $this->auth->refresh($this->auth->getToken()->get());
// Set the token
$this->auth->setToken($token);
// Authenticate a user via a token.
$user = $this->auth->authenticate($token);
// Save user 刷新令牌,并将令牌重新入库
$user->token = $token;
$user->save();
// token被刷新之后,保证本次请求在controller中需要根据token调取登录用户信息能够执行成功
$request->user = $user;
// 将token放在请求中,继续执行,最后将token返回到客户端,做到无痛刷新
$request->token = $token;
$request->headers->set('Authorization', 'Bearer '.$token); //
//Log::info(json_encode($request));
// 继续
return $next($request);
} catch (JWTException $e) {
//Log::info('该令牌已被列入黑名单');
// 过期用户
return response()->json([
'code' => 3003,
'msg' => '该令牌已被列入黑名单,请重新登录!', // The token has been blacklisted
'data' => null,//$e->getMessage(),
'token' => '',
]);
}
} catch (JWTException $e) {
return response()->json([
'code' => 3001,
'msg' => '登录信息已过期,请重新登录!', //token已过期
'data' => null,//$e->getMessage(),
'token' => '',
]);
}
// 令牌验证成功后,继续执行
$response = $next($request);
return $response;
}
}