【问题标题】:Handling AuthenticationFailureResult on client side在客户端处理 AuthenticationFailureResult
【发布时间】:2018-04-17 08:37:33
【问题描述】:

我几乎使用this 方法来使用令牌保护我们的api。不确定,如何在客户端处理令牌到期响应。我在 api 方面看到了两个选项 -

  1. 挑战
  2. WWW-身份验证标头

假设我的客户正在请求联系人列表,但他们的令牌已过期,因为它是 30 分钟前发出的(我们当前的令牌年龄)。我们现在怎么办?

  1. 如果我们再次要求提供凭据,体验会很糟糕
  2. 使用 do-while 循环,直到我们得到成功的响应。我们的客户端是一个插件,因此我们可以将用户的凭据存储在数据库中。
  3. try\catch 也有可能

此时,实施 IdentityServer 和刷新令牌对我们来说太过分了。

【问题讨论】:

    标签: asp.net-web-api oauth-2.0 asp.net-web-api2 jwt access-token


    【解决方案1】:

    在新令牌过期后,您可以通过多种方式处理此问题。每次令牌过期时都要求提供凭据不是一个好的体验。实现此目的的一些方法是使用 MemoryCache 或文本文件来存储您的令牌,然后继续读取它。令牌过期后,获取一个新令牌并替换您之前存储的令牌。下面的示例代码

    public async Task<string> GetToken(HttpClient client)
    {
    
        Token token;
    
        MemoryCache memCache = MemoryCache.Default;
    
        var resource = memCache.Get(Settings.TokenKey);
    
        if (resource.IsNotNull())
        {
    
            token = (Token)resource;
    
            if (token != null && token.Expires < DateTime.Now)
            {
                token = await RequestNewToken(client);
                return token.AccessToken;
            }
        }
    
        token = await RequestNewToken(client);
        return token.AccessToken;
    
    }
    
    private async Task<Token> RequestNewToken(HttpClient client)
    {
        var tokenRequestContent = GetTokenRequestContent();
    
        var tokenResponse = client.PostAsync(Settings.TokenUrl, tokenRequestContent).Result;
    
        Token token = null;
    
        MemoryCache memCache = MemoryCache.Default;
    
        if (tokenResponse.IsSuccessStatusCode)
        {
            token = await tokenResponse.Content.ReadAsAsync<Token>();
            memCache.Add(Settings.TokenKey, token, DateTimeOffset.UtcNow.AddHours(2));
        }
        else
        {
            var error = await tokenResponse.Content.ReadAsStringAsync();
            Console.WriteLine(error);
        }
    
        if (token == null) throw new NullReferenceException("Token is null");
    
        return token;
    }
    
    private FormUrlEncodedContent GetTokenRequestContent()
    {
        var credentials = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("grant_type", Settings.Password),
            new KeyValuePair<string, string>("userName", Settings.Username),
            new KeyValuePair<string, string>("password", Settings.UserPassword)
        };
    
        return new FormUrlEncodedContent(credentials);
    }
    

    Settings 只是一个包含常量的静态类。

    【讨论】:

    • 感谢您清晰的回复。我不想在客户端存储过期逻辑。我正在使用 JwtSecurityToken ,它没有任何到期属性,但从您的代码中获取一个想法 - 我可以围绕它编写一个包装器并从服务器发送到期日期时间。想法?
    猜你喜欢
    • 2016-09-20
    • 2011-01-11
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多