Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppAuth iOS. How to save the token info after user registers an account in my own OAuth2 server

I have an iOS app and a backend written in Spring with OAuth2 mechanizm implemented.

I have a signup endpoint in my backend, which accepts some user data and returns an OAuth2 response, e.g.

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

After that I want to save OIDAuthState in my keychain, so I do the following:

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
    }

Everything works well, but I have an issue when the token expires. The app makes a call to the backend and AppAuth is not able to refresh the token:

OIDAuthState does not have refresh token

I can see, that the refresh token is not present in the OIDAuthState object. I have checked the initialization of the OIDAuthState from OIDAuthorizationResponse and found out that token is not assigned in that case.

Can anybody help how I can save OIDAuthState from the OAuth response I receive from my backend? Or am I doing something in a wrong way?

Thanks,

Osman

like image 542
fiks Avatar asked Nov 01 '17 13:11

fiks


People also ask

What is OAuth in iOS?

OAuth2 lets users grant third-party apps access to their web resources, without sharing their passwords, through a security object known as an access token. OAuth2 works with the following four actors: authorization server: responsible for authentication and authorization; provides the access token.

What is OAuth2?

OAuth 2.0, which stands for “Open Authorization”, is a standard designed to allow a website or application to access resources hosted by other web apps on behalf of a user. It replaced OAuth 1.0 in 2012 and is now the de facto industry standard for online authorization.


1 Answers

I ran into this same issue using AppAuth for iOS (refreshToken was null). I was able to get it working by adding adding "offline_access" to my scopes.

let request = OIDAuthorizationRequest(configuration: configuration!, clientId: self.kClientID, scopes: [OIDScopeOpenID, OIDScopeProfile, "api", "offline_access"], redirectURL: redirectURI! as URL, responseType: OIDResponseTypeCode, additionalParameters: nil)
like image 63
coniferous Avatar answered Sep 17 '22 20:09

coniferous