简体   繁体   English

是否在oauth上缓存访问令牌?

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

I am currently implementing an authentication using oauth2 with Google. 我目前正在使用oauth2与Google实施身份验证。

I've read that I should cache the access token for later, but do I really need to do this? 我已经读过我应该为以后缓存访问令牌,但我真的需要这样做吗?

I thought about storing it encrypted within the session. 我想在会话中加密存储它。 If it expires, I'll get a new token. 如果它到期,我将获得一个新令牌。

Also if I need to cache the token, how do I know to which user it belongs? 此外,如果我需要缓存令牌,我如何知道它属于哪个用户?

I've read that I should cache the access token for later, but do I really need to do this? 我已经读过我应该为以后缓存访问令牌,但我真的需要这样做吗?

Yes, that what is OAuth made for. 是的,OAuth的目的是什么。 The access token is needed to give your app access to a resource at the service provider without providing username and password every time. 需要访问令牌才能让您的应用程序访问服务提供商的资源,而无需每次都提供用户名和密码。

I thought about storing it encrypted within the session. 我想在会话中加密存储它。 If it expires, I'll get a new token. 如果它到期,我将获得一个新令牌。

It looks like you mixed up things here. 看起来你把事情搞混了。 The expiration of a session and of an access token are different things. 会话和访问令牌的到期是不同的事情。 The access token has usually a far longer life time then a session has (eg token: 60 minutes vs session: 15 minutes). 访问令牌通常具有比会话更长的生命周期(例如令牌:60分钟对比会话:15分钟)。

If an access token expires, you need the refresh token to get a new access token. 如果访问令牌过期,则需要刷新令牌以获取新的访问令牌。 If you don't have a refresh token, you have to initiate a grant flow again to get a new access token. 如果您没有刷新令牌,则必须再次启动授权流以获取新的访问令牌。

Also if I need to cache the token, how do I know to which user it belongs? 此外,如果我需要缓存令牌,我如何知道它属于哪个用户?

That's your responsibility to maintain that connection in your DB somewhere. 您有责任在某个地方维护数据库中的连接。 The service provider (in your case Google) does the same on their end, in order to match the access token to an user/resource. 服务提供商(在您的情况下为Google)在其结尾处执行相同操作,以便将访问令牌与用户/资源相匹配。 Regarding your 2nd point: you should also store the refresh token. 关于你的第二点:你还应该存储刷新令牌。


I suggest you have read here: Why is OAuth designed to have request token and access token? 我建议您在此处阅读: 为什么OAuth设计为具有请求令牌和访问令牌?

You should definitely cache your access tokens. 你绝对应该缓存你的访问令牌。 Generating access tokens is expensive, and usually they come with a relatively long expiration time, therefore they can be reused many times, avoiding bombarding the auth server with new requests every time. 生成访问令牌很昂贵,并且通常它们具有相对较长的到期时间,因此它们可以多次重复使用,从而避免每次都使用新请求轰击auth服务器。

As an example, here is a very simple implementation of a cache in Scala. 例如,这是Scala中缓存的一个非常简单的实现。 A class implementing your oauth operations (getToken, refreshToken, etc.) 实现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      
    }
}

and a companion object, implementing the cache. 和一个伴侣对象,实现缓存。 Companion objects in Scala are static, therefore you can create as many instances of your oauth handler class, still have one global cache available. Scala中的伴随对象是静态的,因此您可以创建oauth处理程序类的任意数量的实例,仍然可以使用一个全局缓存。

The cache is a simple map [key, token] where the key could be the "clientId + scope". 缓存是一个简单的映射[key,token],其中键可以是“clientId + scope”。 You want to store different tokens per client and scope. 您希望为每个客户端和范围存储不同的令牌。 The token should contain the access token per se, plus refresh token if available, expiration time, etc. 令牌应包含访问令牌本身,加上刷新令牌(如果可用),到期时间等。

/** 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