Xamarin.Forms получают новый токен, когда сессия закончена - PullRequest
0 голосов
/ 03 марта 2020

У меня есть такой сценарий: приложение Xamarin.Forms, связанное с Web Api 2. Я делаю все запросы и получаю необходимые данные. Теперь, когда срок действия токена сеанса истекает, мне нужно обновить sh токен, но не выходить из системы. Пользователю не нужно знать, когда обновляется токен. Как это организовать, добавить в каждый запрос 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;

            }
        }

PS У меня есть методы для GetToken и RefreshToken в моем Api, и они работают, как организовать обновление?

1 Ответ

1 голос
/ 04 марта 2020

Это действительно зависит от того, какие библиотеки вы используете в своем проекте. Но предположим, что вы используете обычный c# для обработки ваших HTTP-вызовов.

[ВАРИАНТ 1] 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();
        }
    });

Это означает, что Полли попытается выполнить ваш обычный HTTP-вызов, и в случае сбоя, а причина указана в Handle затем запускается механизм повторных попыток, который попытается обновить sh токен и затем повторить ваш запрос. В конце концов, если токен не может быть обновлен, вы выходите из системы. Конечно, все это можно настроить, проверьте документацию Полли.

Обратите внимание, что внутри Handle<T> вы должны поместить правильное исключение. Я просто использовал Exception в качестве заполнителя, так как я не уверен, какое исключение выдается в вашем случае.

Тогда вы бы назвали свой метод с этой политикой:

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

И вы может повторно использовать эту политику для любого вызова, не нужно создавать ее каждый раз.

[ВАРИАНТ 2] DelegatingHandler

Мне здесь будет нужен другой ответ StackOverflow: Как обновить sh токен с помощью IHttpClientFactory

По сути, вы можете перехватывать каждый HTTP-вызов, сделанный через HttpClient, и обновлять / добавлять токен к вашим запросам.

Обратите внимание, что этот ответ не обязывает вас использовать IHttpClientFactory, это также работает для простого HttpClient.

Также немного вне топи c. Возможно, вы захотите найти библиотеки для обработки вызовов htt, например, Retrofit. Это действительно уменьшит количество шаблонного кода.

...