Lock iOS: Saving and Refreshing JWT Tokens

When an authentication is performed with the offline_access scope included, it will return a refresh token that can be used to request a new JWT token and avoid asking the user his/her credentials again.

Heads up! This page is documentation for an outdated version of Lock for iOS (version 1). Check out the Lock v1 to Lock v2 migration guide, for information on migrating to v2, or the Lock v2 Documentation.

We are using SimpleKeychain to handle iOS Keychain access.

First thing we need to do is store the id_token and refresh_token in the iOS Keychain after a successful authentication.

A0LockViewController *controller = ...;
controller.onAuthenticationBlock = ^(A0UserProfile *profile, A0Token *token) {
    A0SimpleKeychain *keychain = [A0SimpleKeychain keychainWithService:@"Auth0"];
    [keychain setString:token.idToken forKey:@"id_token"];
    [keychain setString:token.refreshToken forKey:@"refresh_token"];
    [keychain setData:[NSKeyedArchiver archivedDataWithRootObject:profile] forKey:@"profile"];
    // Other stuff. Don't forget to dismiss lock
};
let controller: A0LockViewController = ...
controller.onAuthenticationBlock = { (profile, token) in
    guard let profile = profile, let token = token else {
        return //it's a sign up
    }
    let keychain = A0SimpleKeychain(service: "Auth0")
    keychain.setString(token.idToken, forKey: "id_token")
    if let refreshToken = token.refreshToken {
        keychain.setString(refreshToken, forKey: "refresh_token")
    }
    keychain.setData(NSKeyedArchiver.archivedData(withRootObject: profile), forKey: "profile")
    // Other stuff. Don't forget to dismiss lock
}

Once you have those stored, you can at any point request a new id_token using either of by calling to Auth0`s delegation endpoint.

Using a non-expired id_token

A0Lock *lock = [A0Lock sharedLock];
A0SimpleKeychain *keychain = [A0SimpleKeychain keychainWithService:@"Auth0"];
NSString* token = [keychain stringForKey:@"id_token"];
A0APIClient *client = [lock apiClient];
[client fetchNewIdTokenWithIdToken:token parameters:nil success:^(A0Token *token) {
    [keychain setString:token.idToken forKey:@"id_token"];
    //Just got a new id_token!
} failure:^(NSError *error) {
    [keychain clearAll]; //Cleaning stored values since they are no longer valid
    //id_token is no longer valid.
    //You should ask the user to login again!.
}];
let keychain = A0SimpleKeychain(service: "Auth0")
if let token = keychain.stringForKey("id_token") {
    let client = A0Lock.sharedLock().apiClient()
    client.fetchNewIdTokenWithIdToken(token,
        parameters: nil,
        success: { token in
            keychain.setString(token.idToken, forKey: "id_token")
            //Just got a new id_token!
        }, failure: { error in
            keychain.clearAll() //Cleaning stored values since they are no longer valid
            //id_token is no longer valid.
            //You should ask the user to login again!.
    })
}

Using refresh_token

A0Lock *lock = [A0Lock sharedLock];
A0SimpleKeychain *keychain = [A0SimpleKeychain keychainWithService:@"Auth0"];
NSString* refreshToken = [keychain stringForKey:@"refresh_token"];
A0APIClient *client = [lock apiClient];
[client fetchNewIdTokenWithRefreshToken:refreshToken parameters:nil success:^(A0Token *token) {
    [keychain setString:token.idToken forKey:@"id_token"];
    //Just got a new id_token!
} failure:^(NSError *error) {
    [keychain clearAll]; //Cleaning stored values since they are no longer valid
    //refresh_token is no longer valid.
    //You should ask the user to login again!.
}];
let keychain = A0SimpleKeychain(service: "Auth0")
if let token = keychain.stringForKey("refresh_token") {
    let client = A0Lock.sharedLock().apiClient()
    client.fetchNewIdTokenWithRefreshToken(token,
        parameters: nil,
        success: { token in
            keychain.setString(token.idToken, forKey: "id_token")
            //Just got a new id_token!
        }, failure: { error in
            keychain.clearAll() //Cleaning stored values since they are no longer valid
            //refresh_token is no longer valid.
            //You should ask the user to login again!.
    })
}

Retrieving the user profile from Keychain

If you need to show profile information in your application, just retrieve the saved profile and pick what you need. For example:

A0SimpleKeychain *keychain = [A0SimpleKeychain keychainWithService:@"Auth0"];
A0UserProfile *profile = [NSKeyedUnarchiver unarchiveObjectWithData:[keychain dataForKey:@"profile"]];
self.nameLabel.text = profile.name;
self.emailLabel.text = profile.email;
let keychain = A0SimpleKeychain(service: "Auth0")
if let data = keychain.dataForKey("profile"), let profile = NSKeyedUnarchiver.unarchiveObjectWithData(data) {
  self.nameLabel.text = profile.name
  self.emailLabel.text = profile.email
}