Skip to content

Commit 1788e54

Browse files
committed
Merge branch 'next' of https://github.com/friendsofthinkphp/think-jwt into next
2 parents d29dd10 + e24e608 commit 1788e54

8 files changed

Lines changed: 149 additions & 65 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ public function login()
109109

110110
## Token 验证
111111

112+
自动获取当前应用(多应用下)配置。
113+
112114
### 手动验证
113115
```php
114116
use xiaodi\JWTAuth\Facade\Jwt;
@@ -135,7 +137,11 @@ class User {
135137
```php
136138
use xiaodi\JWTAuth\Middleware\Jwt;
137139

140+
// 自动获取当前应用配置
138141
Route::get('/hello', 'index/index')->middleware(Jwt::class);
142+
143+
// 自定义应用 使用api应用配置
144+
Route::get('/hello', 'index/index')->middleware(Jwt::class, 'api');
139145
```
140146

141147
## Token 自动获取

src/Config/Token.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ public function getReloginCode()
8282
{
8383
return $this->relogin_code;
8484
}
85+
86+
public function getRefreshCode()
87+
{
88+
return $this->refresh_code;
89+
}
8590

8691
public function getAutomaticRenewal()
8792
{
@@ -92,4 +97,5 @@ public function getTokenType()
9297
{
9398
return $this->type;
9499
}
100+
95101
}

src/Handle/Url.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ class Url extends RequestToken
88
{
99
public function handle()
1010
{
11-
return $this->app->request->param('token');
11+
return $this->app->request->get('token');
1212
}
1313
}

src/Middleware/Jwt.php

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace xiaodi\JWTAuth\Middleware;
66

77
use think\App;
8+
use think\Response;
89
use xiaodi\JWTAuth\Exception\JWTException;
910

1011
/**
@@ -19,25 +20,27 @@ public function __construct(App $app)
1920
$this->app = $app;
2021
}
2122

22-
public function handle($request, \Closure $next)
23+
public function handle($request, \Closure $next, $store = null)
2324
{
24-
// 暂时修复 6.0.3 options 问题
25-
if ($request->isOptions()) {
26-
return $next($request);
25+
if ($request->method(true) == 'OPTIONS') {
26+
return Response::create()->code(204);
2727
}
2828

29-
if (true === $this->app->get('jwt')->verify()) {
30-
31-
$user = $this->app->get('jwt.user');
29+
if (true === $this->app->get('jwt')->store($store)->verify()) {
3230

33-
if ($user->getBind()) {
34-
if ($info = $user->get()) {
31+
if ($this->app->get('jwt.user')->getBind()) {
32+
if ($user = $this->app->get('jwt.user')->find()) {
3533
// 路由注入
36-
$request->user = $info;
34+
$request->user = $user;
3735

3836
// 绑定当前用户模型
39-
$model = $user->getClass();
40-
$this->app->bind($model, $info);
37+
$class = $this->app->get('jwt.user')->getClass();
38+
$this->app->bind($class, $user);
39+
40+
// 绑定用户后一些业务处理
41+
$this->bindUserAfter($request);
42+
} else {
43+
throw new JWTException('登录校验已失效, 请重新登录', 401);
4144
}
4245
}
4346

@@ -46,4 +49,10 @@ public function handle($request, \Closure $next)
4649

4750
throw new JWTException('Token 验证不通过', 401);
4851
}
52+
53+
protected function bindUserAfter($request)
54+
{
55+
// 当前用户
56+
// $request->user
57+
}
4958
}

src/Service/Jwt.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ public function __construct(App $app)
3333
$this->init();
3434
}
3535

36-
public function store(string $store)
36+
public function store(string $store = null): self
3737
{
38-
$this->store = $store;
38+
if ($store) {
39+
$this->store = $store;
40+
}
41+
42+
return $this;
3943
}
4044

4145
public function getStore()
@@ -111,4 +115,19 @@ public function ttl()
111115
{
112116
return $this->app->get('jwt.token')->getRefreshTTL();
113117
}
118+
119+
public function refresh(?string $token = null)
120+
{
121+
return $this->app->get('jwt.token')->refresh($token);
122+
}
123+
124+
public function logout(?string $token = null)
125+
{
126+
return $this->app->get('jwt.token')->logout($token);
127+
}
128+
129+
public function destroyToken($jti, $store)
130+
{
131+
return $this->app->get('jwt.manager')->destroyToken($jti, $store);
132+
}
114133
}

src/Service/Manager.php

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace xiaodi\JWTAuth\Service;
66

77
use Lcobucci\JWT\Token;
8+
use Lcobucci\JWT\Parser;
89
use think\App;
910
use xiaodi\JWTAuth\Config\Manager as Config;
1011

@@ -37,57 +38,61 @@ protected function resloveConfig()
3738

3839
public function login(Token $token): void
3940
{
40-
$jti = $token->getClaim('jti');
41-
$store = $token->getClaim('store');
42-
43-
$exp = $token->getClaim('exp') - time();
44-
4541
if ($this->app->get('jwt.sso')->getEnable()) {
46-
$this->handleSSO($store, $jti, (string) $token, $exp);
42+
$this->handleSSO($token);
4743
}
4844

49-
$this->pushWhitelist($store, $jti, (string) $token, $exp);
45+
$this->pushWhitelist($token);
5046
}
5147

52-
protected function handleSSO($store, $jti, $token, $exp)
48+
protected function handleSSO(Token $token): void
5349
{
54-
$key = $this->formatWhiteKey($store, $jti);
55-
if ($this->app->cache->has($key)) {
56-
$this->clearCache($store, $this->config->getWhitelist(), $jti);
57-
$this->pushBlacklist($store, $jti, (string) $token, $exp);
58-
}
59-
}
50+
$jti = $token->getClaim('jti');
51+
$store = $token->getClaim('store');
52+
$exp = $token->getClaim('exp') - time();
6053

61-
protected function pushWhitelist($store, $jti, string $value, $exp): void
62-
{
63-
$this->setCache($store, $this->config->getWhitelist(), $jti, $value, $exp);
54+
$this->destroyToken($jti, $store);
6455
}
6556

66-
protected function pushBlacklist($store, $jti, string $value, $exp): void
57+
protected function pushWhitelist(Token $token): void
6758
{
68-
$this->setCache($store, $this->config->getBlacklist(), $jti, $value, $exp);
59+
$jti = $token->getClaim('jti');
60+
$store = $token->getClaim('store');
61+
$exp = $token->getClaim('exp') - time();
62+
$tag = $store .'-' . $this->config->getWhitelist();
63+
64+
$key = $this->formatKey($store, $this->config->getWhitelist(), $jti, (string)$token);
65+
$this->setCache($tag, $key, (string)$token, $exp);
6966
}
7067

71-
public function logout(Token $token): void
68+
protected function pushBlacklist(Token $token): void
7269
{
7370
$jti = $token->getClaim('jti');
7471
$store = $token->getClaim('store');
7572

7673
$exp = $token->getClaim('exp') - time();
77-
$this->pushBlacklist($store, $jti, (string) $token, $exp);
74+
$tag = $store .'-' . $this->config->getBlacklist();
75+
$key = $this->formatKey($store, $this->config->getBlacklist(), $jti, (string)$token);
76+
77+
$this->setCache($tag, $key, (string)$token, $exp);
78+
}
79+
80+
public function logout(Token $token): void
81+
{
82+
$this->pushBlacklist($token);
7883
}
7984

8085
public function wasBan(Token $token): bool
8186
{
8287
$jti = $token->getClaim('jti');
8388
$store = $token->getClaim('store');
8489

85-
return $this->getBlacklist($store, $jti) ? true : false;
90+
return $this->getBlacklist($store, $jti, (string)$token) === (string) $token ? true : false;
8691
}
8792

88-
protected function getBlacklist($store, $jti)
93+
protected function getBlacklist(string $store, string $jti, string $token)
8994
{
90-
return $this->getCache($store, $jti, $this->config->getBlacklist());
95+
return $this->getCache($store, $this->config->getBlacklist(), $jti, $token);
9196
}
9297

9398
public function destroyStoreWhitelist($store): void
@@ -102,7 +107,24 @@ public function destroyStoreBlacklist($store): void
102107

103108
public function destroyToken($id, $store): void
104109
{
105-
$this->clearCache($store, $this->config->getWhitelist(), $id);
110+
$type = $this->config->getWhitelist();
111+
$tag = $store .'-' . $type;
112+
113+
$rule = implode(':', [$this->config->getPrefix(), $store, $type, $id]);
114+
$keys = $this->app->cache->getTagItems($tag);
115+
$parser = new Parser();
116+
117+
foreach($keys as $key) {
118+
119+
if (false !== strpos($key, $rule)) {
120+
$value = $this->app->cache->get($key);
121+
122+
if ($value) {
123+
$token = $parser->parse($value);
124+
$this->pushBlacklist($token);
125+
}
126+
}
127+
}
106128
}
107129

108130
protected function clearStoreWhitelist($store): void
@@ -120,26 +142,14 @@ private function clearTag($tag): void
120142
$this->app->cache->tag($tag)->clear();
121143
}
122144

123-
private function setCache($store, $type, $uid, $value, $exp): void
124-
{
125-
$key = $this->formatKey($store, $type, $uid);
126-
127-
$this->app->cache->tag($store . '-' . $type)->set($key, $value, $exp);
128-
}
129-
130-
protected function formatWhitelist($store, $uid): string
131-
{
132-
return $this->formatKey($store, $this->config->getWhitelist(), $uid);
133-
}
134-
135-
protected function formatBlacklist($store, $uid): string
145+
private function setCache($tag, $key, $value, $exp): void
136146
{
137-
return $this->formatKey($store, $this->config->getBlacklist(), $uid);
147+
$this->app->cache->tag($tag)->set($key, $value, $exp);
138148
}
139149

140-
private function formatKey($store, $type, $uid): string
150+
private function formatKey($store, $type, $uid, $value): string
141151
{
142-
$key = implode(':', [$this->config->getPrefix(), $store, $type, $uid]);
152+
$key = implode(':', [$this->config->getPrefix(), $store, $type, $uid, md5($value)]);
143153

144154
return $key;
145155
}
@@ -151,9 +161,9 @@ private function clearCache($store, $type, $uid): void
151161
$this->app->cache->delete($key);
152162
}
153163

154-
private function getCache($store, $uid, $type)
164+
private function getCache($store, $type, $jti, $token)
155165
{
156-
$key = implode('', [$this->config->getPrefix(), $store, $type, $uid]);
166+
$key = implode(':', [$this->config->getPrefix(), $store, $type, $jti, md5($token)]);
157167

158168
return $this->app->cache->get($key);
159169
}

src/Service/Token.php

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ protected function resolveConfig(): array
6464
$store = $this->getStore();
6565
$options = $this->app->config->get("jwt.stores.{$store}.token", []);
6666

67-
return $options;
67+
if (!empty($options)) {
68+
return $options;
69+
}
70+
71+
throw new JWTException($store . '应用 Token 配置未完整', 500);
6872
}
6973

7074
protected function makeId(array $claims)
@@ -138,7 +142,7 @@ protected function automaticRenewalToken(JwtToken $token)
138142
return $token;
139143
}
140144

141-
protected function parseToken(string $token): JwtToken
145+
public function parseToken(string $token): JwtToken
142146
{
143147
try {
144148
$token = (new Parser())->parse($token);
@@ -181,7 +185,7 @@ public function verify(string $token): ?bool
181185
if ($this->config->getAutomaticRenewal()) {
182186
$this->token = $this->automaticRenewalToken($this->token);
183187
} else {
184-
throw new TokenAlreadyEexpired('Token 已过期,请重新刷新', $this->config->getReloginCode());
188+
throw new TokenAlreadyEexpired('Token 已过期,请重新刷新', $this->config->getRefreshCode());
185189
}
186190
} else {
187191
throw new TokenAlreadyEexpired('Token 刷新时间已过,请重新登录', $this->config->getReloginCode());
@@ -207,6 +211,33 @@ public function verify(string $token): ?bool
207211
return true;
208212
}
209213

214+
public function refresh(string $token = null): JwtToken
215+
{
216+
$token = $token ?: $this->getRequestToken();
217+
$token = $this->parseToken($token);
218+
219+
$claims = $token->getClaims();
220+
221+
unset($claims['iat']);
222+
unset($claims['jti']);
223+
unset($claims['nbf']);
224+
unset($claims['exp']);
225+
unset($claims['iss']);
226+
unset($claims['aud']);
227+
228+
$this->app->get('jwt.manager')->logout($token);
229+
230+
return $this->make($claims);
231+
}
232+
233+
public function logout(?string $token = null): void
234+
{
235+
$token = $token ?: $this->getRequestToken();
236+
$token = $this->parseToken($token);
237+
238+
$this->app->get('jwt.manager')->logout($token);
239+
}
240+
210241
/**
211242
* 自动获取请求下的Token.
212243
*

src/Service/User.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ protected function resolveConfig(): array
4444

4545
public function getClass(): string
4646
{
47-
$store = $this->getStore();
48-
$class = $this->config->getClass();
49-
if (!$class) {
47+
$token = $this->app->get('jwt')->getToken();
48+
49+
try {
50+
$class = $token->getClaim('model', $this->config->getClass());
51+
} catch (\OutOfBoundsException $e) {
52+
$store = $this->getStore();
5053
throw new JWTException("{$store}应用未配置用户模型文件");
5154
}
5255

@@ -58,7 +61,7 @@ public function getBind()
5861
return $this->config->getBind();
5962
}
6063

61-
public function get()
64+
public function find()
6265
{
6366
$class = $this->getClass();
6467
$token = $this->app->get('jwt')->getToken();

0 commit comments

Comments
 (0)