AppAuth iOS. Как сохранить информацию о токенах после регистрации пользователем учетной записи на моем собственном сервере OAuth2

У меня есть приложение iOS и бэкэнд, написанный в Spring с реализованным механизмом OAuth2.

У меня есть конечная точка signup в моем бэкэнд, которая принимает некоторые пользовательские данные и возвращает ответ OAuth2, например.

{
    "access_token":"9154140d-b621-4391-9fdd-fbba9e5e4188",
    "token_type":"bearer",
    "refresh_token":"dd612036-7cc6-4858-a30f-c548fc2a823c",
    "expires_in":89,
    "scope":"write"
}

После этого я хочу сохранить OIDAuthState в моей цепочке ключей, поэтому я делаю следующее:

func saveTokenResponse(responseDict: [String: NSCopying & NSObjectProtocol]) {
        let redirectURI = URL(string: kRedirectURI)
        let configuration = OIDServiceConfiguration(authorizationEndpoint: URL(string: kAuthorizationEndpoint)!, tokenEndpoint: URL(string: kTokenEndpoint)!)
        let request = OIDAuthorizationRequest(configuration: configuration, clientId: self.kClientID, scopes: ["write"], redirectURL: redirectURI!, responseType: OIDResponseTypeCode, additionalParameters: nil)

        let accessToken = responseDict["access_token"] ?? nil
        let tokenType = responseDict["token_type"] ?? nil
        let refreshToken = responseDict["refresh_token"] ?? nil
        let expiresIn = responseDict["expires_in"] ?? nil
        let scope = responseDict["scope"] ?? nil

        let response = OIDAuthorizationResponse(request: request, parameters: [
            "access_token": accessToken!,
            "token_type": tokenType!,
            "refresh_token": refreshToken!,
            "expires_in": expiresIn!,
            "scope": scope!
            ]
        )
        let authState = OIDAuthState(authorizationResponse: response) //here authState.refreshToken is nil, so it won't be serialized.

        updateAuthState(authState: authState) // it just saves it in keychain
    }

Все работает хорошо, но у меня проблема, когда токен истекает. Приложение делает звонок на бэкэнд, и AppAuth не может обновить токен:

OIDAuthState не обновляет токен

Я вижу, что токен обновления отсутствует в объекте OIDAuthState. Я проверил инициализацию OIDAuthState из OIDAuthorizationResponse и выяснил, что в этом случае токен не назначен.

Может ли кто-нибудь помочь, как я могу сохранить OIDAuthState из ответа OAuth, который я получаю от моего бэкэнда? Или я делаю что-то не так?

Спасибо,

Осман

Ответ 1

Если ваш токен истекает, вы переходите на экран входа в систему (функция выключения вызова), как и все приложения (банковская система, Amazon, Paytm и Facebook). Поэтому пользователь, когда вы входите в систему с вашими учетными данными, затем получаете те же ответы, что хотите, и нуждаетесь в обновлении токена. У вас есть аналогичная информация в веб-сервисе входа, например, ниже ответа. Я надеюсь, что он отлично работает

    let accessToken = responseDict["access_token"] ?? nil
    let tokenType = responseDict["token_type"] ?? nil
    let refreshToken = responseDict["refresh_token"] ?? nil
    let expiresIn = responseDict["expires_in"] ?? nil
    let scope = responseDict["scope"] ?? nil

    let response = OIDAuthorizationResponse(request: request, parameters: [
        "access_token": accessToken!,
        "token_type": tokenType!,
        "refresh_token": refreshToken!,
        "expires_in": expiresIn!,
        "scope": scope!]
       )

Ответ 2

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

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

  • Маркер доступа, который вы получаете при входе в систему, должен быть отправлен на ваш сервер, чтобы просмотреть и проверить, является ли пользователь аутентичным, и все его личные данные могут быть получены вместе с ним (через вызов GoogleAPI).
  • Отправьте этот токен доступа на свой сервер, как только пользователь войдет в систему через Google. Аутентифицируйте этот токен на стороне сервера.
  • После того, как токен доступа аутентифицирован, отправьте свой собственный уникальный токен с вашего сервера (с истечением срока его действия или нет).
  • Пользователь продолжает использовать приложение с этим уникальным маркером, который вы предоставили.

Ответ 3

Измените строку let redirectURI = URL(string: kRedirectURI) на нижний регистр, oAuth для ios является придирчивым. Также можно попытаться использовать Okta в качестве посредника, который подключается прямо с помощью oAuth.