Manage sessions, sign-out and MFA
Keep a person signed in with refresh tokens, sign them out, and require a fresh sign-in or multi-factor authentication (MFA).
When a person signs in, your project keeps a session for them. Your application never sees the session directly. It sees the tokens issued from it, and each of them names the session in the sid claim.
Use this guide to control that session from your application: keep the person signed in, sign them out, and require a fresh sign-in or multi-factor authentication (MFA) before a sensitive action.
Before you begin
You need:
- An application that signs people in with the authorization code flow. To build one, follow Add sign-in to an app.
- The application's client ID, and its client secret if it has one.
- Your project's issuer, the project's URL. This guide uses
https://acme.authfi.io.
Keep a person signed in
An access token lasts 15 minutes by default. To keep a person signed in for longer, exchange the refresh token for new tokens when the access token expires.
AuthFI issues a refresh token to every application that holds a client secret. An application without a client secret receives one when the project allows it, which it does by default. The setting is Refresh tokens for browser apps, in Settings > Sessions in the console.
POST
/oauth/tokencurl https://acme.authfi.io/oauth/token \
-d grant_type=refresh_token \
-d refresh_token="$REFRESH_TOKEN" \
-d client_id="$CLIENT_ID"$REFRESH_TOKEN is the most recent refresh_token your application received. $CLIENT_ID is the application's client ID. An application with a client secret also sends it, as HTTP Basic authentication or as client_secret in the body.
AuthFI returns new tokens, including a new refresh token:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6Ii4uLiJ9...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "...",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii4uLiJ9...",
"scope": "openid profile email"
}Follow these rules when you refresh:
- Use each refresh token once. Every use returns a new refresh token. Store the new one and discard the old one.
- Ask for the same scopes, or fewer.
scopeon a refresh can be a subset of what was first granted, and never more. - Read the sign-in claims as those of the original sign-in.
sid,amrandauth_timein the new tokens are unchanged. Refreshing does not make a sign-in look newer.
Sign a person out
To sign a person out, send the browser to the project's end-session endpoint.
GET
/oauth/logouthttps://acme.authfi.io/oauth/logout?client_id=CLIENT_ID&post_logout_redirect_uri=https%3A%2F%2Fapp.acme.com%2F&state=abcAuthFI ends the session and removes its cookie. What the person sees next depends on the request:
- When
client_idis given andpost_logout_redirect_urihas the same scheme and host as one of the application's registered redirect URIs, the person is sent back to it. - Otherwise, the person sees a page that says they are signed out.
Signing out ends the session. To also stop the refresh token your application holds, revoke it:
POST
/oauth/token/revokecurl https://acme.authfi.io/oauth/token/revoke \
-d token="$REFRESH_TOKEN" \
-d client_id="$CLIENT_ID"The response is 200 with an empty body. See Revoke a token.
A session also ends without your application, when it reaches its total length or its idle time, or when the person's account is removed. See Session and token lifetimes.
End a session from the console
An administrator can end sessions in two places:
- One or more sessions. Open Security > Sessions, select the rows, and choose End session. Confirm with the End session button, which names how many sessions it ends.
- Every session of one person. Open Identity > Users, open the person's page, and choose Sign out everywhere. The person can sign in again.
Require a fresh sign-in
To make a person sign in again, add one of these parameters to the authorization request.
For example, this request makes the person sign in again and fills in their account name:
echo "https://acme.authfi.io/oauth/authorize?response_type=code&client_id=$CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.acme.com%2Fcallback&scope=openid%20profile%20email&state=$STATE&code_challenge=$CHALLENGE&code_challenge_method=S256&prompt=login&login_hint=ada%40acme.com"$STATE and $CHALLENGE are created as in Add sign-in to an app. The browser returns to your redirect URI with a code, as for any sign-in.
The auth_time claim in the ID token tells you when the person last signed in. When you depend on max_age, check auth_time yourself.
Require MFA
To require multi-factor authentication (MFA) or a passkey, add acr_values to the authorization request. acr stands for authentication context class reference: a name for how strongly the person signed in.
echo "https://acme.authfi.io/oauth/authorize?response_type=code&client_id=$CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.acme.com%2Fcallback&scope=openid%20profile%20email&state=$STATE&code_challenge=$CHALLENGE&code_challenge_method=S256&acr_values=urn%3Aauthfi%3Aacr%3Amfa"Several values, separated by spaces, mean "any of these, or stronger".
If the level you asked for cannot be reached, the browser returns to your redirect URI with error=unmet_authentication_requirements.
Require MFA from the console
acr_values requires MFA for one sign-in to one application. An administrator can also require it in the console, where MFA is labelled Second factor:
- For everyone in the project. Open Settings > Sign-in. Under What they have to prove, set Second factor to Required (at every sign-in). The other choice is Optional (only under risk or a rule). Then choose Review and apply, and apply the change.
- For one person. Open Identity > Users, open the person's page, and choose Require MFA in the More actions menu. The person enrols a factor at their next sign-in.
Check that it works
Send a person through an authorization request with prompt=login and acr_values=urn:authfi:acr:mfa, then exchange the code for tokens. In the new tokens:
auth_timeis the time of the sign-in you just completed.acrisurn:authfi:acr:mfaor a stronger level.amrlists the methods the person used.
Then exchange the refresh token. The response contains a new refresh_token, and auth_time is unchanged.
Session and token lifetimes
A session has two limits. Whichever is reached first ends it.
Tokens have their own lifetimes.
Change the lifetimes
- In the console, open Settings > Sessions.
- Under How long they stay signed in, enter a value in seconds.
- Choose Review and apply, and apply the changes.
A shorter lifetime applies to what is issued next. It does not revoke anything already issued.
Sign-in strength claims
The tokens record what happened at sign-in.
Sign-in protections
These protections apply on the sign-in page of every project. Your application does nothing to turn them on.
A breached password is rejected even when it is the correct one.
To change the lockout numbers, open Settings > Sign-in in the console. Under Failed sign-ins, Lock out after is the number of failed attempts, and Lockout lasts is the time in seconds. To change when a password expires, open Settings > Passwords and set Expires after, in days. In both places, choose Review and apply, and apply the changes.
Troubleshooting
Every error is listed in the endpoint reference.
Next steps
Application types and redirect URIs
Which application types hold a client secret, and how redirect URIs are matched.
Tokens and claims
Every claim in an ID token and an access token.
OAuth and OpenID Connect endpoints
Every parameter of the authorization, token, revocation and end-session endpoints.
Add sign-in with another identity provider
Let people sign in with an account they already have.