天天看點

聊聊 OAuth 2.0 的 token expire_in 使用

問題背景

有同學私信問了這樣的問題,通路 pig4cloud 的

示範環境

檢視登入請求 network 傳回封包如下:

{
    "access_token":"16d35799-9cbb-4c23-966d-ab606029a623",
    "token_type":"bearer",
    "refresh_token":"495dbde5-1bbb-43c9-b06b-ecac50aa5d53",
    "expires_in":41000,
    "scope":"server"
}           

而本地部署運作的時,登入請求傳回的封包如下:

{
    "access_token":"c262afbe-441e-4023-afb4-f88c8a0a7d51",
    "token_type":"bearer",
    "refresh_token":"ea642d50-5cf5-48ad-9ef9-cb57c9dde00a",
    "scope":"server"
}           

缺少

expires_in

過期參數,是以用戶端無法知悉何時執行重新整理行為。

源碼剖析

我們來看下 oauth2 的令牌方法機制,如果用戶端 配置的 validitySeconds (令牌有效期) 大于 0 會傳回目前令牌的有效時間 expires_in 參數,

OAuth2AccessToken createAccessToken() {
  DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());
  int validitySeconds = getAccessTokenValiditySeconds(authentication.getOAuth2Request());
  if (validitySeconds > 0) {
    token.setExpiration(new Date(System.currentTimeMillis() + (validitySeconds * 1000L)));
  }
  token.setRefreshToken(refreshToken);
  token.setScope(authentication.getOAuth2Request().getScope());

  return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token;
}           
  • tokenStore 去存儲 令牌的時候,若過期參數為 0 或者 小于 0 Expiration 為空,不會設定有效時間也就意味着為永久有效,是以此時不會用戶端響應 expires_in 參數
if (token.getExpiration() != null) {
  int seconds = token.getExpiresIn();
  conn.expire(accessKey, seconds);
  conn.expire(authKey, seconds);
  conn.expire(authToAccessKey, seconds);
  conn.expire(clientId, seconds);
  conn.expire(approvalKey, seconds);
}           
聊聊 OAuth 2.0 的 token expire_in 使用

永久有效的令牌是否應該傳回 expires_in 參數呢?

我們先來看下

oauth2 協定規範
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
  "scope":"create"
}           
  • access_token (必需) 授權伺服器發出的通路令牌
  • token_type (必需)這是令牌的類型,通常隻是字元串“bearer”。
  • expires_in (推薦)如果通路令牌過期過期時間。
  • refresh_token(可選)重新整理令牌,在通路令牌過期後,可使用此令牌重新整理。
  • scope(可選)如果使用者授予的範圍與應用程式請求的範圍相同,則此參數為可選。

此處 expires_in 推薦傳回,無論是有設定有效期限制還是無有效期限制。是以此處 spring security oauth2 的處理并不符合協定規範 emmm 。

聊聊 OAuth 2.0 的 token expire_in 使用