繁体   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