Sign users out
Each sign-in stack has its own logout route, and each one behaves differently. Use the section for your stack.
| Stack | Endpoint | Needs a signed-in user | CSRF | What it ends |
|---|---|---|---|---|
| Cookie | POST /identity/logout | Yes | Yes | The application, external, two-factor, remember-client, and ReAuth cookies |
| Identity bearer | POST /identity/logout | Yes | No | Cookies only. Bearer tokens stay valid until they expire. |
| JWT | POST /auth/logout | No | Yes | The refresh-token family and the refresh cookie |
Sign out of the cookie stack
- Get a CSRF token from
GET /identity/csrfToken. - Send
POST /identity/logoutwithcredentials: 'include'and theRequestVerificationTokenheader.const { csrfToken } = await fetch('/identity/csrfToken', { credentials: 'include' }).then(r => r.json()); await fetch('/identity/logout', { method: 'POST', credentials: 'include', headers: { 'RequestVerificationToken': csrfToken } });
Logout signs out of the Identity.Application, Identity.External, Identity.TwoFactorUserId, Identity.TwoFactorRememberMe, and AuthEndpoints.ReAuth schemes. Because it clears the remember-client cookie, the next password login from that browser asks for a 2FA code again.
Sign out of the Identity bearer stack
Send POST /identity/logout with the Authorization: Bearer <accessToken> header. No CSRF token is needed.
This call clears cookies only. It does not revoke the access token or the refresh token. To end the session on the client, delete both tokens from storage. The tokens stay valid on the server until they expire.
Sign out of the JWT stack
- Get a CSRF token from
GET /auth/csrfToken. - Send
POST /auth/logoutwithcredentials: 'include'and theRequestVerificationTokenheader. - Delete the access token from client memory.
The endpoint does not require a signed-in user. It revokes the whole refresh-token family of the cookie it receives, deletes the cookie, and returns 200. The access token stays valid until it expires (15 minutes by default, AccessTokenLifetime).