@@ -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 }
0 commit comments