在 .Net Core 中实现刷新令牌功能的最佳位置?
Posted
技术标签:
【中文标题】在 .Net Core 中实现刷新令牌功能的最佳位置?【英文标题】:Best place to implement Refresh token functionality in .Net Core? 【发布时间】:2021-09-23 08:32:45 【问题描述】:我们希望使用身份服务器中的刷新令牌生成新的访问令牌。我们希望实现与 SPA 应用程序类似的场景(反应中的静默更新令牌,角度)。目前,我们已经在 Index 部分实现了它,但这里的问题是每当我加载页面时,只有在刷新令牌的帮助下才会生成新的访问令牌。
public async Task<IActionResult> IndexAsync()
string accessToken = string.Empty;
var currentContext = _httpContextAccessor.HttpContext;
var expires_at = await currentContext.GetTokenAsync("expires_at");
if (string.IsNullOrWhiteSpace(expires_at)
|| ((DateTime.Parse(expires_at).AddSeconds(-60)).ToUniversalTime()
< DateTime.UtcNow))
accessToken = await RenewTokens();
else
accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var content = await client.GetStringAsync("https://xxxxxxx");
ViewData["Token"] = content;
ViewData["AccessToken"] = accessToken;
return View();
public async Task<String> RenewTokens()
var currentContext = _httpContextAccessor.HttpContext;
var refreshToken = await HttpContext.GetTokenAsync("refresh_token");
var client = new HttpClient();
var values = new Dictionary<string, string>
"client_id", "xxx" ,
"client_secret", "xxxx" ,
"grant_type", "refresh_token" ,
"scope", "xxxx" ,
"refresh_token", refreshToken
;
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https:///xxxxxx/token", content);
var jsonContent = await response.Content.ReadAsStringAsync();
Token tok = JsonConvert.DeserializeObject<Token>(jsonContent);
string access_token = tok.AccessToken;
var ExpiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tok.ExpiresIn);
var authenticationInfo = await currentContext.AuthenticateAsync("Cookies");
authenticationInfo.Properties.UpdateTokenValue("expires_at", ExpiresAt.ToString("o", CultureInfo.InvariantCulture));
authenticationInfo.Properties.UpdateTokenValue("access_token", tok.AccessToken);
authenticationInfo.Properties.UpdateTokenValue("refresh_token", tok.RefreshToken);
await currentContext.SignInAsync("Cookies", authenticationInfo.Principal, authenticationInfo.Properties);
return access_token;
【问题讨论】:
【参考方案1】:避免仅基于 expires_at 进行更新,因为由于时钟差异和竞争条件,它没有弹性。在某些设置中,您可能会因为其他原因收到 401,例如令牌签名证书续订。
职责应该是这样的:
客户端使用访问令牌尝试 API 请求 如果客户端收到 401,它会尝试静默刷新访问令牌并使用新令牌重试 API 请求 如果您的“SPA”通过 Web 后端发送所有数据请求,您可以在 C# 代码中执行此操作以下是弹性客户端的一些示例代码:
Web Mobile【讨论】:
我们正在寻找 .net 核心而非 SPA 的解决方案 虽然是相同的设计模式 - 如果您使用 HttpClient in C# 发出 API 请求,您将编写类似的代码以上是关于在 .Net Core 中实现刷新令牌功能的最佳位置?的主要内容,如果未能解决你的问题,请参考以下文章
使用 redux saga 在 react native 中实现令牌刷新