在 .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 中实现刷新令牌功能的最佳位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中实现刷新令牌

如何在ios中实现刷新令牌

使用 redux saga 在 react native 中实现令牌刷新

如何在.net core mvc的搜索框中实现自动完成功能?

.Net Core API JWT 令牌验证

如何使 Identity Core 生成的访问令牌无效?