CredentialsManager
public struct CredentialsManager
Credentials management utility for securely storing and retrieving the user’s credentials from the Keychain.
-
Creates a new
CredentialsManager
instance.Declaration
Swift
public init(authentication: Authentication, storeKey: String = "credentials", storage: CredentialsStorage = A0SimpleKeychain())
Parameters
authentication
Auth0 Authentication API client.
storeKey
Key used to store user credentials in the Keychain. Defaults to
credentials
.storage
The
CredentialsStorage
instance used to manage credentials storage. Defaults to a standardA0SimpleKeychain
instance. -
Retrieves the user information from the Keychain synchronously, without checking if the credentials are expired. The user information is read from the stored ID Token.
let user = credentialsManager.user
Important
Access to this property will not be protected by Biometric authentication.Declaration
Swift
public var user: UserInfo? { get }
-
Enables Biometric authentication for additional security during credentials retrieval.
credentialsManager.enableBiometrics(withTitle: "Touch to Login")
If needed, you can specify a particular
LAPolicy
to be used. E.g. you might want to support Face ID or Touch ID, but also allow fallback to passcode.credentialsManager.enableBiometrics(withTitle: "Touch or enter passcode to Login", evaluationPolicy: .deviceOwnerAuthentication)
Declaration
Swift
public mutating func enableBiometrics(withTitle title: String, cancelTitle: String? = nil, fallbackTitle: String? = nil, evaluationPolicy: LAPolicy = LAPolicy.deviceOwnerAuthenticationWithBiometrics)
Parameters
title
Main message to display when Face ID or Touch ID is used.
cancelTitle
Cancel message to display when Face ID or Touch ID is used.
fallbackTitle
Fallback message to display when Face ID or Touch ID is used after a failed match.
evaluationPolicy
Policy to be used for authentication policy evaluation.
-
Stores a credentials instance in the Keychain.
let didStore = credentialsManager.store(credentials: credentials)
Declaration
Swift
public func store(credentials: Credentials) -> Bool
Parameters
credentials
Credentials instance to store.
Return Value
If the credentials were stored.
-
Clears credentials stored in the Keychain.
let didClear = credentialsManager.clear()
Declaration
Swift
public func clear() -> Bool
Return Value
If the credentials were removed.
-
Calls the
/oauth/revoke
endpoint to revoke the Refresh Token and then clears the credentials if the request was successful. Otherwise, the credentials will not be cleared and the callback will be called with a failure result containing arevokeFailed
error.credentialsManager.revoke { result in switch result { case .success: print("Revoked Refresh Token and cleared credentials") case .failure(let error): print("Failed with: \(error)") } }
If you need to specify custom headers for the Refresh Token revocation:
credentialsManager.revoke(headers: ["key": "value"]) { print($0) }
If no Refresh Token is available the endpoint is not called, the credentials are cleared, and the callback is invoked with a success case.
See
Refresh TokensDeclaration
Swift
public func revoke(headers: [String : String] = [:], _ callback: @escaping (CredentialsManagerResult<Void>) -> Void)
Parameters
headers
Additional headers to use when revoking the Refresh Token.
callback
Callback that receives a
Result
containing either an empty success case or an error. -
Checks that there are credentials stored, and that the Access Token has not expired and will not expire within the specified TTL.
guard credentialsManager.hasValid() else { // No valid credentials exist, present the login page } // Retrieve stored credentials
See
expiresIn
Declaration
Swift
public func hasValid(minTTL: Int = 0) -> Bool
Parameters
minTTL
Minimum lifetime in seconds the Access Token must have left. Defaults to
0
.Return Value
If there are credentials stored containing an Access Token that is neither expired or about to expire.
-
Retrieves credentials from the Keychain and yields new credentials using the Refresh Token if the Access Token is expired. Otherwise, the retrieved credentials will be returned via the success case as they are not expired. Renewed credentials will be stored in the Keychain.
credentialsManager.credentials { result in switch result { case .success(let credentials): print("Obtained credentials: \(credentials)") case .failure(let error): print("Failed with: \(error)") } }
To avoid retrieving Access Tokens with too little time left, you can enforce a minimum TTL:
credentialsManager.credentials(minTTL: 60) { print($0) }
If you need to specify custom parameters or headers for the credentials renewal:
credentialsManager.credentials(parameters: ["key": "value"], headers: ["key": "value"]) { print($0) }
When renewing credentials you can get a downscoped Access Token by requesting fewer scopes than were requested on login. If you specify fewer scopes, the credentials will be renewed immediately, regardless of whether they are expired or not.
credentialsManager.credentials(scope: "openid offline_access") { print($0) }
Requires
The scopeoffline_access
to have been requested on login to get a Refresh Token from Auth0. If the credentials are expired and there is no Refresh Token, the callback will be called with a failure case containing anoRefreshToken
error.Note
This method is thread-safe.See
Refresh TokensDeclaration
Swift
public func credentials(withScope scope: String? = nil, minTTL: Int = 0, parameters: [String : Any] = [:], headers: [String : String] = [:], callback: @escaping (CredentialsManagerResult<Credentials>) -> Void)
Parameters
scope
Space-separated list of scope values to request when renewing credentials. Defaults to
nil
, which will ask for the same scopes that were requested on login.minTTL
Minimum time in seconds the Access Token must remain valid to avoid being renewed. Defaults to
0
.parameters
Additional parameters to use when renewing credentials.
headers
Additional headers to use when renewing credentials.
callback
Callback that receives a
Result
containing either the user’s credentials or an error. -
-
Enables Biometric authentication for additional security during credentials retrieval.
credentialsManager.enableBiometrics(withTitle: "Touch to Login")
If needed, you can specify a particular
LAPolicy
to be used. E.g. you might want to support Face ID or Touch ID, but also allow fallback to passcode.credentialsManager.enableBiometrics(withTitle: "Touch or enter passcode to Login", evaluationPolicy: .deviceOwnerAuthentication)
-
Calls the
/oauth/revoke
endpoint to revoke the Refresh Token and then clears the credentials if the request was successful. Otherwise, the credentials are not cleared and the subscription completes with an error.credentialsManager .revoke() .sink(receiveCompletion: { completion in switch completion { case .finished: print("Revoked Refresh Token and cleared credentials") case .failure(let error): print("Failed with: \(error)") } }, receiveValue: {}) .store(in: &cancellables)
If you need to specify custom headers for the Refresh Token revocation:
credentialsManager .revoke(headers: ["key": "value"]) .sink(receiveCompletion: { print($0) }, receiveValue: {}) .store(in: &cancellables)
If no Refresh Token is available the endpoint is not called, the credentials are cleared, and the subscription completes without an error.
See
Refresh TokensDeclaration
Swift
func revoke(headers: [String : String] = [:]) -> AnyPublisher<Void, CredentialsManagerError>
Parameters
headers
Additional headers to use when revoking the Refresh Token.
Return Value
A type-erased publisher.
-
Retrieves credentials from the Keychain and yields new credentials using the Refresh Token if the Access Token is expired. Otherwise, the subscription will complete with the retrieved credentials as they are not expired. Renewed credentials will be stored in the Keychain.
credentialsManager .credentials() .sink(receiveCompletion: { completion in if case .failure(let error) = completion { print("Failed with: \(error)") } }, receiveValue: { credentials in print("Obtained credentials: \(credentials)") }) .store(in: &cancellables)
To avoid retrieving Access Tokens with too little time left, you can enforce a minimum TTL:
credentialsManager .credentials(minTTL: 60) .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &cancellables)
If you need to specify custom parameters or headers for the credentials renewal:
credentialsManager .credentials(parameters: ["key": "value"], headers: ["key": "value"]) .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &cancellables)
When renewing credentials you can get a downscoped Access Token by requesting fewer scopes than were requested on login. If you specify fewer scopes, the credentials will be renewed immediately, regardless of whether they are expired or not.
credentialsManager .credentials(scope: "openid offline_access") .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &cancellables)
Requires
The scopeoffline_access
to have been requested on login to get a Refresh Token from Auth0. If the credentials are expired and there is no Refresh Token, the subscription will complete with anoRefreshToken
error.Note
This method is thread-safe.See
Refresh TokensDeclaration
Swift
func credentials(withScope scope: String? = nil, minTTL: Int = 0, parameters: [String : Any] = [:], headers: [String : String] = [:]) -> AnyPublisher<Credentials, CredentialsManagerError>
Parameters
scope
Space-separated list of scope values to request when renewing credentials. Defaults to
nil
, which will ask for the same scopes that were requested on login.minTTL
Minimum time in seconds the Access Token must remain valid to avoid being renewed. Defaults to
0
.parameters
Additional parameters to use when renewing credentials.
headers
Additional headers to use when renewing credentials.
Return Value
A type-erased publisher.
-
revoke(headers:
Asynchronous) Declaration
Swift
func revoke(headers: [String : String] = [:]) async throws
-
credentials(withScope:
AsynchronousminTTL: parameters: headers: ) Declaration
Swift
func credentials(withScope scope: String? = nil, minTTL: Int = 0, parameters: [String : Any] = [:], headers: [String : String] = [:]) async throws -> Credentials