Skip to content

Commit 7a01f1f

Browse files
committed
#6 过期自动续签
1 parent 32e4650 commit 7a01f1f

3 files changed

Lines changed: 81 additions & 29 deletions

File tree

config/config.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
'relogin' => 50002,
1414
'iss' => '',
1515
'aud' => '',
16+
'automaticRenewal' => false,
1617
],
1718
'user' => [
1819
'inject' => false,

src/Jwt.php

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,12 @@ class Jwt
3232
*/
3333
private $manager;
3434

35-
/**
36-
* @var Builder
37-
*/
38-
private $builder;
39-
4035
use \xiaodi\JWTAuth\Traits\Jwt;
4136

42-
public function __construct(App $app, Manager $manager, Builder $builder, User $user)
37+
public function __construct(App $app, Manager $manager, User $user)
4338
{
4439
$this->app = $app;
4540
$this->manager = $manager;
46-
$this->builder = $builder;
4741
$this->user = $user;
4842

4943
$config = $this->getConfig();
@@ -73,19 +67,23 @@ public function token(array $claims): Token
7367
{
7468
$uniqid = $this->makeTokenId($claims);
7569

76-
$this->builder->setIssuer($this->iss())
70+
$exp = time() + $this->ttl();
71+
$refreshAt = $exp + $this->refreshTTL();
72+
73+
$builder = new Builder();
74+
$builder->setIssuer($this->iss())
7775
->setAudience($this->aud())
7876
->setId($uniqid, true)
7977
->setIssuedAt(time())
8078
->setNotBefore(time() + $this->notBefore())
81-
->setExpiration(time() + $this->ttl())
82-
->set('refreshAt', time() + $this->refreshTTL());
79+
->setExpiration($exp)
80+
->set('refreshAt', $refreshAt);
8381

8482
foreach ($claims as $key => $claim) {
85-
$this->builder->set($key, $claim);
83+
$builder->set($key, $claim);
8684
}
8785

88-
$token = $this->builder->getToken($this->getSigner(), $this->makeSignerKey());
86+
$token = $builder->getToken($this->getSigner(), $this->makeSignerKey());
8987

9088
$this->manager->login($token);
9189

@@ -169,9 +167,13 @@ protected function getRequestToken(): Token
169167
*
170168
* @return Token
171169
*/
172-
public function parseToken(): Token
170+
public function parseToken($token): Token
173171
{
174-
$token = $this->getRequestToken();
172+
try {
173+
$token = (new Parser())->parse($token);
174+
} catch (\InvalidArgumentException $e) {
175+
throw new JWTInvalidArgumentException('此 Token 解析失败', 500);
176+
}
175177

176178
return $token;
177179
}
@@ -185,9 +187,9 @@ public function parseToken(): Token
185187
*/
186188
public function logout(Token $token = null)
187189
{
188-
$this->token = $token ?: $this->getRequestToken();
190+
$token = $token ?: $this->getRequestToken();
189191

190-
$this->manager->logout($this->token);
192+
$this->manager->logout($token);
191193
}
192194

193195
/**
@@ -199,57 +201,94 @@ public function logout(Token $token = null)
199201
*/
200202
public function verify(Token $token = null)
201203
{
202-
$this->token = $token ?: $this->getRequestToken();
204+
$token = $token ?: $this->getRequestToken();
203205

204206
try {
205-
$this->validateToken();
207+
$this->validateToken($token);
208+
$this->token = $token;
206209
} catch (\BadMethodCallException $e) {
207210
throw new JWTException('此 Token 未进行签名', 500);
208211
}
209212

210213
return true;
211214
}
212215

216+
/**
217+
* Token 自动续期
218+
*
219+
* @param Token $token
220+
* @param int|string $ttl 秒数
221+
* @return void
222+
*/
223+
protected function automaticRenewalToken(Token $token)
224+
{
225+
$this->logout($token);
226+
$claims = $token->getClaims();
227+
228+
unset($claims['iat']);
229+
unset($claims['jti']);
230+
unset($claims['nbf']);
231+
unset($claims['exp']);
232+
unset($claims['iss']);
233+
unset($claims['aud']);
234+
unset($claims['refreshAt']);
235+
236+
$token = $this->token($claims);
237+
$claims = $token->getClaims();
238+
$refreshAt = $claims['refreshAt'];
239+
240+
header('Access-Control-Expose-Headers:Automatic-Renewal-Token,Automatic-Renewal-Token-RefreshAt');
241+
header("Automatic-Renewal-Token:$token");
242+
header("Automatic-Renewal-Token-RefreshAt:$refreshAt");
243+
244+
return $token;
245+
}
246+
213247
/**
214248
* 效验 Token.
215249
*
216250
* @return void
217251
*/
218-
protected function validateToken()
252+
protected function validateToken(Token $token)
219253
{
220254
// 是否在黑名单
221-
if ($this->manager->hasBlacklist($this->token)) {
255+
if ($this->manager->hasBlacklist($token)) {
222256
throw new TokenAlreadyEexpired('此 Token 已注销,请重新登录', $this->getReloginCode());
223257
}
224258

225259
// 验证密钥是否与创建签名的密钥一致
226-
if (false === $this->token->verify($this->getSigner(), $this->makeSignerKey())) {
260+
if (false === $token->verify($this->getSigner(), $this->makeSignerKey())) {
227261
throw new JWTException('此 Token 与 密钥不匹配', $this->getReloginCode());
228262
}
229263

230264
// 是否可用
231-
$exp = $this->token->getClaim('nbf');
265+
$exp = $token->getClaim('nbf');
232266
if (time() < $exp) {
233267
throw new JWTException('此 Token 暂未可用', 500);
234268
}
235269

236270
// 是否已过期
237-
if (true === $this->token->isExpired()) {
238-
if (time() <= $this->token->getClaim('refreshAt')) {
239-
throw new TokenAlreadyEexpired('Token 已过期,请重新刷新'.time().'-'.$this->token->getClaim('refreshAt'), $this->getAlreadyCode());
271+
if (true === $token->isExpired()) {
272+
if (time() <= $token->getClaim('refreshAt')) {
273+
// 是否开启自动续签
274+
if ($this->automaticRenewal()) {
275+
$token = $this->automaticRenewalToken($token);
276+
} else {
277+
throw new TokenAlreadyEexpired('Token 已过期,请重新刷新', $this->getAlreadyCode());
278+
}
279+
} else {
280+
throw new TokenAlreadyEexpired('Token 刷新时间已过,请重新登录', $this->getReloginCode());
240281
}
241-
242-
throw new TokenAlreadyEexpired('Token 刷新时间已过,请重新登录', $this->getReloginCode());
243282
}
244283

245284
$data = new ValidationData();
246285

247-
$jwt_id = $this->token->getHeader('jti');
286+
$jwt_id = $token->getHeader('jti');
248287
$data->setIssuer($this->iss());
249288
$data->setAudience($this->aud());
250289
$data->setId($jwt_id);
251290

252-
if (!$this->token->validate($data)) {
291+
if (!$token->validate($data)) {
253292
throw new JWTException('此 Token 效验不通过', $this->getReloginCode());
254293
}
255294
}

src/Traits/Jwt.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ trait Jwt
2727
private $iss;
2828
private $aud;
2929

30+
private $automaticRenewal = false;
31+
3032
/**
3133
* 获取 Token获取途径.
3234
*
@@ -267,4 +269,14 @@ public function getToken()
267269
{
268270
return $this->token;
269271
}
272+
273+
/**
274+
* 获取 是否开启过期自动续签
275+
*
276+
* @return void
277+
*/
278+
public function automaticRenewal()
279+
{
280+
return $this->automaticRenewal;
281+
}
270282
}

0 commit comments

Comments
 (0)