Обновление токена доступа p2 / OAuth2 iOS - PullRequest
0 голосов
/ 16 июня 2020

Я использую p2 / OAuth2 с Alamofire v4, как описано в документации здесь

let sessionManager = SessionManager()
let retrier = OAuth2RetryHandler(oauth2: <# your OAuth2 instance #>)
sessionManager.adapter = retrier
sessionManager.retrier = retrier
self.alamofireManager = sessionManager   // you must hold on to this somewhere
// Note that the `validate()` call here is important
sessionManager.request("https://api.github.com/user").validate().responseJSON { response in
    debugPrint(response)
}
import Foundation
import OAuth2
import Alamofire


class OAuth2RetryHandler: RequestRetrier, RequestAdapter {

    let loader: OAuth2DataLoader

    init(oauth2: OAuth2) {
        loader = OAuth2DataLoader(oauth2: oauth2)
    }

    /// Intercept 401 and do an OAuth2 authorization.
    public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
        if let response = request.task?.response as? HTTPURLResponse, 401 == response.statusCode, let req = request.request {
            var dataRequest = OAuth2DataRequest(request: req, callback: { _ in })
            dataRequest.context = completion
            loader.enqueue(request: dataRequest)
            loader.attemptToAuthorize() { authParams, error in
                guard error?.asOAuth2Error != .alreadyAuthorizing else {
                    // Don't dequeue requests if we are waiting for other authorization request
                    return
                }
                self.loader.dequeueAndApply() { req in
                    if let comp = req.context as? RequestRetryCompletion {
                        comp(nil != authParams, 0.0)
                    }
                }
            }
        }
        else {
            completion(false, 0.0)   // not a 401, not our problem
        }
    }

    /// Sign the request with the access token.
    public func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
        guard nil != loader.oauth2.accessToken else {
            return urlRequest
        }
        return try urlRequest.signed(with: loader.oauth2)   // "try" added in 3.0.2
    }
}

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

Возможно ли реализовать этот подход?

Заранее спасибо, С уважением,

1 Ответ

0 голосов
/ 16 июня 2020

Что ж, стандартное поведение в мобильном приложении должно быть следующим:

  • Войдите и получите токен доступа + refre sh токен
  • При необходимости храните токены в безопасном хранилище, чтобы Исключение входов в систему при каждом перезапуске приложения
  • Использование токена доступа для вызова API и обработки ответов 401 через обновление токена
  • Использование токена refre sh для обновления токена доступа при необходимости
  • В конце концов токен refre sh истекает, и пользователь должен снова войти в систему.

Вы никогда не сможете полностью избежать ответа 401 от API, и пользовательские интерфейсы должны обрабатывать этот ответ специально. В качестве оптимизации можно автоматически обновлять sh токенов в фоновом режиме до того, как будет достигнуто требование 'exp' из текущего токена доступа.

Из интереса есть код iOS Пример моего , который легко запустить и который позволяет тестировать события истечения срока действия. Это может дать вам некоторые идеи о том, как адаптировать собственное решение.

...