我目前正在與Google一起使用oauth2進行身份驗證。在oauth上緩存訪問令牌?
我讀過我應該爲以後緩存訪問令牌,但我真的需要這樣做嗎?
我想過在會話中加密存儲它。如果過期了,我會得到一個新的令牌。
另外,如果我需要緩存令牌,我怎麼知道它屬於哪個用戶?
我目前正在與Google一起使用oauth2進行身份驗證。在oauth上緩存訪問令牌?
我讀過我應該爲以後緩存訪問令牌,但我真的需要這樣做嗎?
我想過在會話中加密存儲它。如果過期了,我會得到一個新的令牌。
另外,如果我需要緩存令牌,我怎麼知道它屬於哪個用戶?
我讀過我應該爲以後緩存訪問令牌,但我真的需要這樣做嗎?
是的,那是什麼OAuth造就的。需要訪問令牌來讓您的應用訪問服務提供商處的資源,而無需每次都提供用戶名和密碼。
我想過在會話中加密存儲它。如果它 到期,我會得到一個新的令牌。
看起來你在這裏混淆了一些東西。會話和訪問令牌的到期是不同的事情。訪問令牌通常具有比會話長得多的壽命(例如令牌:60分鐘比會話:15分鐘)。
如果訪問令牌到期,您需要刷新令牌來獲取新的訪問令牌。如果您沒有刷新令牌,則必須再次啓動授權流程以獲取新的訪問令牌。
此外,如果我需要緩存令牌,我怎麼知道它 屬於哪個用戶?
這是您的責任,在您的數據庫的某處維護該連接。服務提供商(在你的情況下,谷歌)在他們的最後做同樣的事情,以便將訪問令牌與用戶/資源相匹配。關於你的第二點:你還應該存儲刷新令牌。
,我建議你在這裏閱讀:Why is OAuth designed to have request token and access token?
你絕對應該緩存您訪問令牌。生成訪問令牌非常昂貴,通常它們的到期時間相對較長,因此可以多次重複使用,避免每次都向新的請求轟炸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],其中key可以是「clientId +範圍」。您想要爲每個客戶端和作用域存儲不同的令牌。令牌應包含訪問令牌本身,如果可用,還包含刷新令牌,到期時間等。
/** 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
}
}