【问题标题】:Caching the access token on oauth or not?是否在 oauth 上缓存访问令牌?
【发布时间】:2016-03-21 15:48:23
【问题描述】:

我目前正在使用 oauth2 和 Google 实施身份验证。

我读到我应该缓存访问令牌以备后用,但我真的需要这样做吗?

我考虑过将其加密存储在会话中。如果过期,我会得到一个新的令牌。

另外,如果我需要缓存令牌,我如何知道它属于哪个用户?

【问题讨论】:

    标签: java oauth


    【解决方案1】:

    我已经读到我应该缓存访问令牌以备后用,但我是否 真的需要这样做吗?

    是的,这就是 OAuth 的用途。需要访问令牌才能让您的应用访问服务提供商处的资源,而无需每次都提供用户名和密码。

    我考虑过将其加密存储在会话中。如果它 过期了,我会得到一个新的令牌。

    看起来你在这里搞混了。会话的到期和访问令牌的到期是不同的事情。访问令牌的生命周期通常比会话长得多(例如令牌:60 分钟 vs 会话:15 分钟)。

    如果访问令牌过期,您需要刷新令牌来获取新的访问令牌。如果您没有刷新令牌,则必须再次启动授权流程以获取新的访问令牌。

    另外,如果我需要缓存令牌,我怎么知道它是给哪个用户的 属于?

    您有责任在数据库中的某个地方维护该连接。服务提供商(在您的情况下为 Google)在他们的末端做同样的事情,以便将访问令牌与用户/资源匹配。关于您的第二点:您还应该存储刷新令牌。


    我建议你在这里阅读:Why is OAuth designed to have request token and access token?

    【讨论】:

      【解决方案2】:

      您绝对应该缓存您的访问令牌。生成访问令牌的成本很高,而且通常具有相对较长的到期时间,因此可以多次重复使用,避免每次都用新请求轰炸身份验证服务器。

      作为一个例子,这里有一个非常简单的 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
         }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-10-08
        • 1970-01-01
        • 2016-01-19
        • 2021-10-26
        • 2021-09-13
        • 2019-07-23
        • 1970-01-01
        • 2018-02-28
        • 2016-12-12
        相关资源
        最近更新 更多