在.Net Core中实现刷新令牌功能的最佳位置



我们希望使用身份服务器中的刷新令牌生成一个新的访问令牌。我们希望实现与SPA应用程序类似的场景(react中的静默续订令牌,angular(。目前,我们已经在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;
}

避免仅基于expires_at进行续订,因为它由于时钟差异和种族条件而不具有弹性。在某些设置中,您可能会因为其他原因获得401,例如令牌签名证书续订。

责任应该是这样的:

  • 客户端尝试使用访问令牌的API请求
  • 如果客户端收到401,则尝试静默刷新访问令牌,并使用新令牌重试API请求
  • 如果您的"SPA"通过Web后端发送所有数据请求,您可以在C#代码中执行此操作

以下是一些弹性客户端的示例代码:

  • Web
  • Mobile

相关内容

  • 没有找到相关文章

最新更新