簡體   English   中英

是否在oauth上緩存訪問令牌?

[英]Caching the access token on oauth or not?

我目前正在使用oauth2與Google實施身份驗證。

我已經讀過我應該為以后緩存訪問令牌,但我真的需要這樣做嗎?

我想在會話中加密存儲它。 如果它到期,我將獲得一個新令牌。

此外,如果我需要緩存令牌,我如何知道它屬於哪個用戶?

我已經讀過我應該為以后緩存訪問令牌,但我真的需要這樣做嗎?

是的,OAuth的目的是什么。 需要訪問令牌才能讓您的應用程序訪問服務提供商的資源,而無需每次都提供用戶名和密碼。

我想在會話中加密存儲它。 如果它到期,我將獲得一個新令牌。

看起來你把事情搞混了。 會話和訪問令牌的到期是不同的事情。 訪問令牌通常具有比會話更長的生命周期(例如令牌:60分鍾對比會話:15分鍾)。

如果訪問令牌過期,則需要刷新令牌以獲取新的訪問令牌。 如果您沒有刷新令牌,則必須再次啟動授權流以獲取新的訪問令牌。

此外,如果我需要緩存令牌,我如何知道它屬於哪個用戶?

您有責任在某個地方維護數據庫中的連接。 服務提供商(在您的情況下為Google)在其結尾處執行相同操作,以便將訪問令牌與用戶/資源相匹配。 關於你的第二點:你還應該存儲刷新令牌。


我建議您在此處閱讀: 為什么OAuth設計為具有請求令牌和訪問令牌?

你絕對應該緩存你的訪問令牌。 生成訪問令牌很昂貴,並且通常它們具有相對較長的到期時間,因此它們可以多次重復使用,從而避免每次都使用新請求轟擊auth服務器。

例如,這是Scala中緩存的一個非常簡單的實現。 實現oauth操作的類(getToken,refreshToken等)

class authHandler private(serviceURL: java.net.URL) {

  def getToken(clientId: String,
               clientSecret: String,
               scope: String,
               resource: String = ""): Future[String] = {

    val cacheKey = clientId + scope

    S2SAuthHandler.getTokenFromCache(cacheKey) match {
      case Some(tk) => Future(tk)
      case None => requestTokenFromServer(clientId, clientSecret, scope, resource)
    }
  }

  private def requestTokenFromServer(clientId: String,
                                     clientSecret: String,
                                     scope: String,
                                     resource: String): Future[String] = {

        val authToken = <http request from server>

//expiration time is set to a few seconds less than the one provided from the server, to avoid returning an already expired token. 
        authToken.expires = authToken.expires - 5 + System.currentTimeMillis() / 1000  S2SAuthHandler.storeTokenToCache(clientId + scope, authToken)


    authToken.accessToken      
    }
}

和一個伴侶對象,實現緩存。 Scala中的伴隨對象是靜態的,因此您可以創建oauth處理程序類的任意數量的實例,仍然可以使用一個全局緩存。

緩存是一個簡單的映射[key,token],其中鍵可以是“clientId + scope”。 您希望為每個客戶端和范圍存儲不同的令牌。 令牌應包含訪問令牌本身,加上刷新令牌(如果可用),到期時間等。

/** Companion objec  */
object authHandler {

  private val tokenCache = mutable.Map.empty[String, AuthToken]

  private def getTokenFromCache(cacheKey: String): Option[String] = {
    if ((tokenCache contains cacheKey) && (tokenCache(cacheKey).expires > System.currentTimeMillis / 1000)) {
      Some(tokenCache(cacheKey).accessToken)
    }
    else {
      None
    }
  }

  private def storeTokenToCache(key: String, tk: AuthToken) = {
    tokenCache(key) = tk

//Depending on your execution environment, I would recommend to encrypt the token before storing in the cache
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM