访问令牌和刷新令牌的存储位置和方式

Posted

技术标签:

【中文标题】访问令牌和刷新令牌的存储位置和方式【英文标题】:Where and how to store the access token and refresh token 【发布时间】:2019-10-25 19:26:01 【问题描述】:

我有一个 dotnet core 2.2 MVC web 应用程序,它使用 web api 来执行一些数据库查询。我已经为 web api 实现了基于 JWT 令牌的身份验证。令牌在 api 处生成,Web 应用程序已收到访问令牌、到期令牌和刷新令牌。我需要将此令牌详细信息存储在我的客户端,以便我可以使用它来访问 Web api(到期前)或在令牌过期时使用刷新令牌生成新令牌。

对此的任何帮助将不胜感激。

【问题讨论】:

令牌应该存储在 cookie 中,但请确保您从服务器设置它 你能解释一下吗? 看看下面我的回答 【参考方案1】:

以前的答案没有对使用这些解决方案的原因提供明确的解释。

典型系统如下图所示,WEB 中使用了两种常见的客户端应用程序架构:

在浏览器中运行的单页应用程序 服务器端 MVC 应用程序

在 SPA 的情况下,令牌存储在浏览器(会话存储或本地存储)中,并在过期时由浏览器或应用程序本身自动清除。 仅供参考,出于安全原因,在 SPA 中无法获取刷新令牌。

如果是 MVC 应用程序(您的情况),事情会变得更加复杂。您有两个选择:将其存储在仅 http cookie 或某些外部会话存储中。 Aspnet 核心支持这两种情况,但每种情况都有一些警告。 A good article here。简而言之,如果您担心 cookie 大小,请使用 分布式会话存储,这会增加系统架构的复杂性。否则 cookie 是最简单的解决方案,并且在 aspnet core 中默认启用,您只需要设置 options.StoreTokens = trueoptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme

【讨论】:

【参考方案2】:

有多种方法可以存储令牌。通常应用程序不会在任何地方存储访问令牌,但它们会将刷新令牌存储在永久存储中。

我们来看看web端和api端需要存储什么。

首先,用户将请求使用凭据登录 Web 应用程序,Web 应用程序会将这个请求传递给与 DB 交互的 api 项目。

现在,api 将生成访问令牌和刷新令牌,并将刷新令牌保存到该数据库。然后,Web api 需要将访问令牌和刷新令牌存储在 cookie 或会话等临时存储中。

访问令牌过期时;您需要调用一个新令牌,这将更新数据库中之前的刷新令牌。

TL;DR

刷新令牌 - 在数据库中

访问令牌和刷新令牌-web临时存储

【讨论】:

是的,你是对的。现在我需要实现第二部分,即“访问令牌和刷新令牌 - Web 临时存储”。然后只有我可以发送访问令牌和刷新令牌以获取新令牌。 我有一个问题,如果我将访问令牌存储在数据库中,可能存在哪些安全漏洞? 好问题!正如您所认为的将访问令牌存储在数据库中;您需要在每次请求进入时调用您的数据库,只是为了验证用户,这会增加系统的额外负载。 @NoorAshuvo【参考方案3】:

您有多种选择(安全的 http-only cookie、本地存储、会话存储等)。

在最简单的情况下,您可以将其存储在 cookie 中,以便与每个请求一起发送:

cookie 应始终具有HttpOnly 标志,以防止浏览器中的 XSS 攻击。 cookie 还应在生产中使用Secure 标志,以确保 cookie 仅通过 HTTPS 发送。 保护您的表单免受 CSRF 攻击(例如,通过使用 ASP.NET Core 的 AntiForgery 功能)。

【讨论】:

【参考方案4】:

从 ui 调用 Web 应用程序服务器(控制器)控制器,该控制器又调用以从 api 获取令牌。 从 api 响应中获取令牌并将其存储在 cookie 中。

你的控制器应该看起来像这样

var option = new CookieOptions

    Expires = DateTime.Now.AddMinutes(response.ExpiresIn)
;

if (!string.IsNullOrEmpty(domain))

                option.Domain = domain;


Response.Cookies.Append(cookiename, response.AccessToken, option);

【讨论】:

以上是关于访问令牌和刷新令牌的存储位置和方式的主要内容,如果未能解决你的问题,请参考以下文章

在理解刷新令牌、存储它们的位置和方式以及存储内容方面需要帮助

Node.js 护照 OAuth 2.0 身份验证:存储访问和刷新令牌的位置

jwt 访问令牌和刷新令牌流

我应该将使用 DDD 和 CQRS 方式刷新访问令牌的代码放在哪里?

在 JavaScript 中存储刷新令牌,获取新的访问令牌

为命令存储访问和刷新令牌