Xamarin.Forms在会话结束时获取新令牌

问题描述 投票:0回答:1

我有这种情况:与Web Api 2连接的Xamarin.Forms应用程序。我发出所有请求并获取所需的数据。现在,当会话令牌过期时,我需要刷新令牌,但不注销用户。用户不需要知道何时刷新令牌。如何组织它,在我发送请求时添加每个请求if语句,并检查令牌是否过期。这是我的要求之一:

   public async Task<User> GetProfileSetup()
        {
            try
            {
                if (CrossConnectivity.Current.IsConnected)
                {
                    string token = DependencyService.Get<ISharedFunctions>().GetAccessToken();

                    client.DefaultRequestHeaders.Clear();
                    client.DefaultRequestHeaders.Add("Accept", "application/json");
                    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);

                    var response = await client.GetAsync(@"api/Profile/GetProfilSetup");
                    if (response.IsSuccessStatusCode)
                    {
                        string jsonMessage;
                        using (Stream responseStream = await response.Content.ReadAsStreamAsync())
                        {
                            jsonMessage = new StreamReader(responseStream).ReadToEnd();
                        }
                        User user = JsonConvert.DeserializeObject<User>(jsonMessage);


                        return user;
                    }
                    else
                    {
                        var m = response.Content.ToString();
                        return null;
                    }

                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                string error = ex.Message;
                return null;

            }
        }

P.S我的Api中有用于GetToken和RefreshToken的方法,它们正在起作用,只是如何组织刷新?

xamarin.forms xamarin.android xamarin.ios
1个回答
0
投票

这实际上取决于您在项目中使用的是什么库。但是,假设您正在使用普通的c#来处理HTTP调用。

[OPTION 1] Polly

我可以推荐您查看Polly

这是一个很棒的图书馆,具有很多功能。您可以使用Retry策略来处理过期的令牌:

var _unauthorizedPolicy = Policy
    .Handle<Exception>(ex => ex.StatusCode == HttpStatusCode.Unauthorized) // check here for your exception to be the right one
    .RetryAsync(3, async (exception, retryCount, context) =>
    {
        try
        {
            var token = await _authService.RefreshToken();
            // save the new token or whatever you need to store it
        }
        catch (Exception ex)
        {
            // RefreshToken failed, you should probably sign out the user
            SignOut();
        }
    });

这是Polly将尝试执行您的常规HTTP调用,并且如果失败并且在Handle中指定了原因,则将触发重试机制,该机制将尝试刷新令牌,然后重试您的请求。最后,万一令牌无法刷新,您可以注销用户。当然,所有这些都可以自定义,请检查Polly的文档是否写得很好。

[请注意,您必须在Handle<T>内放置正确的例外。我只是使用Exception作为占位符,因为我不确定在您的情况下会抛出什么异常。

然后您将使用此策略调用方法:

var result = await _unauthorizedPolicy.ExecuteAsync(() => GetProfileSetup())

并且您可以将该策略重用于任何呼叫,而无需每次都创建它。

[OPTION 2] DelegatingHandler

我在这里想要另一个StackOverflow答案:How to Refresh a token using IHttpClientFactory

基本上,您可以拦截通过HttpClient进行的每个HTTP调用,并刷新/向请求添加令牌。

请注意,答案并不强制您使用IHttpClientFactory,它也适用于简单的HttpClient

也有点偏离主题。您可能需要查找库来处理诸如修图之类的htt调用。它将真正减少样板代码的数量。

© www.soinside.com 2019 - 2024. All rights reserved.