Запросите новый токен доступа и повторите запрос API

Я использую библиотеку Refit с моим проектом форм Xamarin для отправки запросов API. Это прекрасно работает, но есть проблема, когда срок действия маркера доступа истекает.

Когда срок действия маркера доступа истекает, я получаю ошибку 401 с сервера, как и ожидалось. Затем я звоню на Identity Server, чтобы выдать новый токен доступа, но у меня возникают трудности при повторной отправке запроса API. Я все еще получаю несанкционированную ошибку. Ценю некоторую помощь.

Я создал класс AuthenticatedHttpClientHandler для обработки токена.

public class AuthenticatedHttpClientHandler : HttpClientHandler
{
    private readonly string _token;

    public AuthenticatedHttpClientHandler(string token ) 
    {
        _token = token;       
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var auth = request.Headers.Authorization;
        if (auth != null && !string.IsNullOrWhiteSpace(_token))
        {
            request.Headers.Authorization = new AuthenticationHeaderValue(auth.Scheme, _token);
        }
        else
        {
            request.Headers.Remove("Authorization");
        }
        var result = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
        if (result.StatusCode == System.Net.HttpStatusCode.Unauthorized )
        {
            IdSrvApiService idsrvApiService = new IdSrvApiService();
            RefreshTokenService refreshTokneService = new RefreshTokenService(idsrvApiService);

            if( Settings.RefreshToken != ""){
                var newToken = await refreshTokneService.RefreshAccessToken(Priority.Background).ConfigureAwait(false);
                TokenHelper.CacheToken(newToken);
                request.Headers.Authorization = new AuthenticationHeaderValue(auth.Scheme, Settings.AccessToken);
                return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                return result;
            }
        }
        else
        {
            return result;
        }
    }
}

3 ответа

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

Существует также вероятность того, что вы отправите неправильный токен со второй попытки. Подтвердите, что значение в newToken это то, что используется через Settings.AccessToken

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

Но я никогда не пытаюсь обновить токен. В вашем коде вы хотите refresh_token, но вы отправляете запрос с access_token. Может быть, это твоя вина.

 var newToken = await refreshTokneService.RefreshAccessToken(Priority.Background).ConfigureAwait(false);

Я думаю, у вас есть проблема в этом методе.

Проверьте, отправляет ли ваша служба маркеров обновления правильные заголовки и параметры в тексте сообщения http.

Заголовки:

  • Принять: приложение / JSON

Тело:

  • grant_type: refresh_token
  • client_id: ваш идентификатор клиента (если применимо)
  • client_secret: ваш клиентский секрет (если применимо)
  • refresh_token: свойство токена обновления (refresh_token), возвращаемое при получении токена доступа.

Убедитесь, что вы передаете правильный Content-Type (application/x-www-form-urlencoded) внутри запроса заголовка тела ( /questions/30974219/c-httpwebrequest-tipa-applicationx-www-form-urlencoded-kak-otpravit-simvol-and-v-tele-soderzhimogo/30974233#30974233 или используйте FormUrlEncodedContent для создания и кодирования содержимого).

Другие вопросы по тегам