Recently we introduced a helper class available here to handle Auth0 Credentials. Usage is simple: Once you create a new instance by passing an AuthenticationAPIClient
(to renew credentials) and a Storage
(to do persistance), you can call any of this 2 public methods:
saveCredentials
: To synchronously save a pair of credentials in the storage. Will throw if the access_token or id_token is null, or if the expires_at date is missing.getCredentials
: To asynchronously get a pair of credentials from the storage.- If no credentials were stored before the methods fails.
- If stored credentials have expired (expires_at > now) and no refresh_token was saved the method fails.
- If the call to renew the credentials using the refresh_token fails, the method fails.
- In any other case, a valid pair of credentials is returned. Either the existing and non-expired ones or a fresh new pair.
As a side note, if the credentials were expired AND refreshed successfully they are NOT updated in the storage. It's up to the user to call again saveCredentials
and persist the new value.
-
Check "logged in" status: When the main screen of the app is first shown and the developer needs to check whether a user has already logged in or not. With the current implementation it will be something like:
- Call
getCredentials
- If the method succeeds the user has "previously logged in". After that the tokens are discarded as the dev doesn't need them now and also doesn't know if the method had just refreshed the tokens or if they were already valid.
- On the other side, if the method fails the dev must check if the exception is of type
Auth0Exception
(or whatever the Authentication client throws) which will mean that it was a network error (either timeout or server rejected the refresh_token) to discard that from a non-existent or expired token.
- Call
-
Store a "logged in" status: User logs in by using Auth0's Authentication API and persists the credentials in the storage.
- Calls
saveCredentials
to save the credentials.
- Calls
-
Authenticate against an API: User needs to send the token in a header to his API.
- He calls
getCredentials
expecting either a valid/fresh pair of credentials or an error. - An error would mean that either the credentials have expired or they couldn't be renewed. If the call fails, he can decide wether to retry if it was a network problem or force the user to log in again.
- He calls
-
Remove the "logged in" status (aka log out): User logs out and the developer needs to ensure that the next time he asks if a user was logged in, the answer is NOPE. With the current implementation it's not possible, as the
saveCredentials
method will null-check the access_token and refresh_token.
It's discussable but (1) can be handled by the developer locally (outside our SDK scope). He must save a boolean/flag to indicate the "logged in" status. If he also stores the expires_at date he's covered, in other case he's not and he may get false positives if he tries to use expired credentials.
Another option is that we provide a method hasCredentials
or hasValidCredentials
that without performing a network request (this is the WIN part) it can tell the developer with 99% success rate that a valid pair of credentials is available in the storage. How will the logic be??
- User calls a sync method
hasCredentials
expecting a boolean. - If credentials exists and they haven't expired (expires_at < now) it will return
true
. - If expired credentials exists but a refresh_token is available, it will return
true
. As this works locally/offline it's not possible to determine if a refresh_token was revoked, but it's a very rare case as it's done via dashboard or Management API. This is the 1%. - On any other case, return
false
.
This is definitely missing. We must provide a way for the developer to clear the existing credentials. A simple method that sets to null or removes the existing entries from the storage. Proposed name is clearCredentials
.
So we can agree (4)
clearCredentials
This proposed
boolean
is basically a convenience wrapper aroundgetCredentials
(without the potential final API call torenew
so it can be sync) . The question is, do we really need to do this for the user? It is easy to add functionality to an API but not easy to remove. In regards to naming I think 'hasCredentials' is better, rather not add guarantees of 'valid' to the name.I do not have strong feelings on this and in general I would lean to the side of helping the user, so this is fine.
Also if we are adding a
clearCredentials
method, let's use it to auto clear credentials that have expired as part of our general logic.I've added to Trello.