我应该如何存储由 RESTful API 生成的令牌?

How should I store a token generated by a RESTful API?

我已经构建了一个 API 为登录的用户生成身份验证令牌。此时我还有一个用 Node.JS.
编写的客户端应用程序 当我使用客户端应用程序的用户凭据向 API 发出请求时,我得到了身份验证令牌:我应该如何将其存储在客户端应用程序中?我不应该每次请求 API 时都请求令牌,对吗?
我考虑过将令牌放在 Cookie 中,但我认为这不是最佳解决方案。 你会推荐什么?

成功登录后,应在服务器端创建一个唯一的一次性令牌,并根据用户 ID 和时间戳将其存储在数据库中。您将令牌存储在 cookie 客户端中。然后,您将令牌传递给每个后续 API 调用。然后服务器应检查令牌是否有效(即未过期、发布或更新少于 30 分钟前)。如果它有效,您可以检索针对该令牌存储的用户详细信息并执行您需要的任何后端功能(当用户通过身份验证时)。然后,您更新该令牌的时间戳(刷新会话,因为您希望登录在 30 分钟无用户交互后超时)。如果在收到 API 调用时令牌已过期或不存在,请重定向到登录页面。

此外,您可能已经知道这一点,但请确保令牌是唯一且不可猜测的,我倾向于生成新的随机 GUID 并对其进行加密,不要使用连续尾 ID 或类似的东西。

我认为这个 link 可以帮助你:

事实上,您应该有一个带有到期日期的令牌,这样您就不必每次都在发送请求之前获取一个新的令牌。当令牌过期时,您只需从服务 "refresh token".

获取一个新令牌

关于如何在客户端应用程序中存储令牌的问题,我认为您可以将其保存在内存中(地图或嵌入式数据库)。

否则结束,我认为在这种用例中使用 cookie 不是一个好主意。

希望对您有所帮助。 蒂埃里

我们正在开发一个使用非常相似方法的应用程序。客户端应用程序是静态 HTML5/JS 单页应用程序(没有任何服务器端生成)并与 API 服务器通信。

最好的方法是将会话令牌存储在内存中:即在 JS 代码中的变量中。如果您的客户端应用程序是单个页面,那应该不是问题。
除此之外,我们还将会话令牌保存在 sessionStorage 中,以便在用户刷新页面时保存它。为了在创建新选项卡时保留令牌(sessionStorage 特定于浏览器 window),我们还在页面关闭时将其存储在 localStorage 中,连同打开选项卡的计数器(当应用程序的所有选项卡时已关闭,我们删除令牌。

// Handle page reloads using sessionStorage
var sess = sessionStorage.getItem('session-token')
if(sess && sess !== 'null') { // Sometimes empty values are a string "null"
    localStorage.setItem('session-token', sess)
}

// Set a counter to check when all pages/tabs of the application are closed
var counter = parseInt(localStorage.getItem('session-counter') || 0, 10)
counter++
localStorage.setItem('session-counter', counter)

// Event fired when the page/tab is closing
window.onbeforeunload = function() {
    var counter = parseInt(localStorage.getItem('session-counter') || 0, 10)
    counter--
    localStorage.setItem('session-counter', counter)

    // All pages are closed: remove the session token
    if(counter <= 0) {
        // Handle page reloads using sessionStorage
        sessionStorage.setItem('session-token', localStorage.getItem('session-token'))

        localStorage.removeItem('session-token')
    }
}

有关 localStorage 和 sessionStorage 的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API

为什么 cookie 不行? cookie 不好有两个原因: 1.它们一般比较持久,跨浏览器windows和标签页共享,即使关闭浏览器也能持久存在。 2. 然而,最重要的是,根据 HTTP 规范,每次发出请求时都必须将它们发送到 Web 服务器。如果您正在设计客户端与 API 服务器完全分离的应用程序,您不希望客户端的服务器在任何情况下都看到(或记录!)会话令牌。

一些额外的建议:

  1. 会话令牌必须过期。您可以通过将会话令牌存储在服务器上的数据库中并在每个请求 and/or "signing" 上验证它们来实现这一点(以纯文本形式向令牌添加时间戳,然后添加签名部分,例如一个 HMAC 散列,时间戳用你只知道的密钥编码)。
  2. 令牌在其生命周期内可以重复使用多次。但是,在一定秒数后,您可能希望服务器刷新令牌,使旧令牌无效并向客户端发送新令牌。