-
Notifications
You must be signed in to change notification settings - Fork 71
feat: add Anonymous Sessions documentation #1455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
BcnCarlos
wants to merge
44
commits into
main
Choose a base branch
from
feat/anonymous-sessions
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
971884b
feat: add Anonymous Sessions documentation
BcnCarlos b8fd7a0
fix: address P1 style guide findings in Anonymous Sessions docs
BcnCarlos 99f00bd
fix: address P2 style guide findings in Anonymous Sessions docs
BcnCarlos 72cf0a9
Update
BcnCarlos 2791ed3
feat: add anonymous session workflow diagram
BcnCarlos 9d17ea1
update
BcnCarlos 49a4255
Update
BcnCarlos 2650950
update mermaid
BcnCarlos 0092672
update mermaid
BcnCarlos 5cb01dc
update mermaid
BcnCarlos b566c45
update
BcnCarlos e3dacd8
update mermaid
BcnCarlos 7fe0fd8
update
BcnCarlos f190323
Delete main/docs/images/cdy7uua7fh8z/anonymous-sessions/anonymous-ses…
BcnCarlos 12975c3
update mermaid
BcnCarlos 7dd7d8c
Update navigation, remove claims, rename quickstart, added session to…
BcnCarlos 936dabd
Update release, mermaid code,
BcnCarlos accaa45
Update code samples
BcnCarlos edef9a6
updated uses cases
BcnCarlos 00bfe6c
update mermaid
BcnCarlos 56877a5
remove old article, edited use cases.
BcnCarlos 3a1a578
Removed dashboard steps from configure anonymous sessions article
BcnCarlos d1b8703
Update configure anonymous sessions code samples
BcnCarlos 071a56a
removed best practices article , clean navigation, edited configurati…
BcnCarlos 65e2919
Updated user cases and configuration article
BcnCarlos e83956e
Update session tokens and anonymous sessions article
BcnCarlos 0b30d59
grammar check
BcnCarlos dd30ff5
update anonymous sessions article
BcnCarlos 9b8172d
Added suggestion from PM
BcnCarlos 885082a
updated warning
BcnCarlos a1df022
Update learn more links
BcnCarlos a4b4a2d
Updated sample codes
BcnCarlos b6dc0a1
updated descriptions
BcnCarlos 12575e2
update code samples
BcnCarlos 6bbefe6
Update code sample
BcnCarlos 83ffde1
udpate code samples
BcnCarlos 98f430b
Apply suggestion from @avanscoy
BcnCarlos 94af780
Apply suggestion from @avanscoy
BcnCarlos 85ac631
Apply suggestion from @avanscoy
BcnCarlos fa67f39
Apply suggestion from @avanscoy
BcnCarlos 88e32b3
Update using suggestions
BcnCarlos c0aa940
Apply suggestion from @avanscoy
BcnCarlos 45c548a
Update suggestions
BcnCarlos e343ad1
Apply suggestions
BcnCarlos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| --- | ||
| title: Anonymous Sessions | ||
| description: Learn how to create and manage user sessions without requiring authentication. | ||
| --- | ||
|
|
||
| import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx" | ||
|
|
||
| <ReleaseStageNotice | ||
| feature="Anonymous Sessions" | ||
| stage="beta" | ||
| terms="true" | ||
| contact="Auth0 Support" | ||
| /> | ||
|
|
||
| Anonymous sessions allow you to create and manage [user sessions](/docs/manage-users/sessions) without requiring authentication. | ||
|
|
||
| Users can browse, add items to carts or wishlists, complete purchases, and set preferences before creating an account. Users then bring their activity into their authenticated profile when they sign up or log in. | ||
|
|
||
| Use anonymous sessions for the following use cases: | ||
|
|
||
| - **Track guest users** across page loads and sessions | ||
| - **Store metadata** such as shopping cart references, preferences, consents, and profiling information | ||
| - **Issue access tokens** for API calls without requiring authentication | ||
| - **Transfer anonymous activity** to authenticated accounts when users sign up or log in | ||
|
|
||
| <Warning> | ||
| Auth0 anonymous session Metadata is not a secure data store and should not be used to store sensitive information. | ||
| This includes secrets and high-risk PII like social security numbers or credit card numbers, etc. | ||
|
|
||
| Additionally, the data stored in an anonymous session is not verified for truthness or accuracy and should never be taken at face value. | ||
|
|
||
| Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for session tagging and access management purposes. | ||
| To learn more, read [Auth0 General Data Protection Regulation Compliance](/docs/secure/data-privacy-and-compliance/gdpr)." | ||
| </Warning> | ||
|
|
||
| ## How it works | ||
|
|
||
| ### Gather anonymous sessions data | ||
|
|
||
| When you decide to start gathering information about a user, even one who has not authenticated yet, your application sends a `POST` request to the `/anonymous/token` endpoint. | ||
|
|
||
| Auth0 responds with two tokens: | ||
|
|
||
| - A [**session token**](/docs/secure/tokens/session-tokens) that identifies and persists the anonymous session. | ||
| - An [**access token**](/docs/secure/tokens/access-tokens) that the user can present to your [resource servers (APIs)](/docs/get-started/apis). | ||
|
|
||
| Subsequent calls that include the session token continue the same session for the same `user_id`, so all activity is traceable to a single origin. | ||
| Using the access token, anonymous users can call any of your existing APIs. | ||
|
|
||
| ```mermaid actions={false} | ||
| sequenceDiagram | ||
| participant app as SPA/APP | ||
| participant idp as Auth0 | ||
| participant rs as Resource Server | ||
| note over app: User Browses the site and <br> we decide to start <br> storing information about them. | ||
| app ->> idp: POST /anonymous/token<br>{language: EN, country: US, order_id: PO123} | ||
| idp ->> app: Session Token, Access Token<br>sub: anon@1234-5678-90 | ||
| note over app: User buys something anonymously. | ||
| app ->>+ rs: POST /purchase<br> Authorization: Bearer <Access Token> | ||
| rs ->> rs: Purchase order PO123 created<br>user_id: anon@1234-5678-90 | ||
| rs ->>- app: HTTP 200 OK | ||
| note over app: User retrieves their anonymous purchases | ||
| app ->> rs: GET /purchase<br> Authorization: Bearer <Access Token> | ||
| rs ->> app: HTTP 200 OK {purchases: ["PO123"]} | ||
| ``` | ||
|
|
||
| ```json Anonymous session data of user anon@1234-5678-90 | ||
| { | ||
| "user_id": "anon@1234-5678-90", | ||
| "session_id": "sess_456", | ||
| "metadata": { | ||
| "language": "EN", | ||
| "country": "US", | ||
| "purchase": "P0123" | ||
| } | ||
| } | ||
| ``` | ||
| ### Transfer anonymous sessions data to user's metadata | ||
|
|
||
| When a user who has an anonymous session decides to log in or sign up, your application passes the `anonymous_session_token` to the `/authorize` endpoint using a cookie or an HTTP header. | ||
|
|
||
| ```javascript cookie example | ||
| // No extra code needed — cookie is sent automatically | ||
| await auth0.loginWithRedirect(); | ||
| ``` | ||
|
|
||
| ```javascript authorize endpoint example | ||
| GET /authorize? | ||
| client_id: YOUR_CLIENT_ID& | ||
| redirect_uri: https://YOUR_ClIENT_URL/callback& | ||
| response_type: code& | ||
| scope: openid& | ||
| Auth0-Anonymous-Session: eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0... | ||
| ``` | ||
|
|
||
| ```mermaid actions={false} | ||
| sequenceDiagram | ||
| participant app as SPA/APP | ||
| participant idp as Auth0 | ||
| participant rs as Resource Server | ||
| note over app: User has been browsing the site | ||
| anonymously and now logs in. | ||
| app ->>+ idp: POST /authorize?client_id=xxx... | ||
| Cookie: auth0_anon=eJY... | ||
| idp ->> idp: Run post-login actions, includes anonymous_session data | ||
| (language, country, order_id) | ||
| idp ->> idp: api.idToken.addCustomClaim('original_uid', event.anonymous_session.user_id) | ||
| idp ->>- app: Access Token, ID Token (with original_uid claim), auth0 cookie | ||
| app ->>+ rs: Get /purchase?user:anon@1234-5678-90 | ||
| rs ->> rs: Purchase order PO123 created by | ||
| user_id: anon@1234-5678-90 | ||
| rs ->>- app: HTTP 200 OK {purchase_orders: ["PO123"]} | ||
| ``` | ||
|
|
||
| Auth0 makes the anonymous session data available in your [`pre-user-registration`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/pre-user-registration-trigger) and [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Actions triggers using the `event.anonymous_session` object. | ||
|
|
||
| ```json anonymous session object | ||
| { | ||
| "anonymous_session": { | ||
| "user_id": "anon@1234-5678-90", | ||
| "session_id": "sess_123", | ||
| "created_at": "2026-05-14T10:30:00Z", | ||
| "metadata": { | ||
| "language": "en", | ||
| "country": "US", | ||
| "order_id": "PO123" | ||
| } | ||
| } | ||
| } | ||
|
BcnCarlos marked this conversation as resolved.
|
||
| ``` | ||
|
|
||
| To learn more about anonymous sessions with Actions, read [Anonymous Sessions Use Cases](/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases). | ||
|
|
||
| ### End the anonymous session after transfer | ||
|
|
||
| Anonymous sessions are not automatically invalidated when a user authenticates. To end the session use the `/anonymous/logout` endpoint: | ||
|
|
||
| ```javascript wrap lines | ||
| // In your application, after successful login | ||
| if (wasAnonymousSession) { | ||
| await fetch('https://YOUR_DOMAIN/anonymous/logout', { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| credentials: 'include', // Send cookies | ||
| body: JSON.stringify({ client_id: 'YOUR_CLIENT_ID' }), | ||
| }); | ||
| } | ||
| ``` | ||
|
|
||
| ## Best practices | ||
|
|
||
| Here are some best practices for anonymous sessions: | ||
|
|
||
| - Configure appropriate [anonymous session lifetimes](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#configure-anonymous-sessions-in-your-auth0-tenant) to avoid losing a user's anonymous session data; Auth0 recommends a lifetime of 30 days or longer. | ||
|
|
||
| - Select anonymous session's [JSON Web Encryption (JWE)](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#configure-anonymous-sessions-in-your-auth0-tenant) encryption to ensure that potential attackers cannot see the contents of the session. | ||
|
|
||
| - Restrict what anonymous `anon@` users can do in your API. | ||
|
|
||
| - Validate tokens and sanitize metadata, never trust metadata or tokens from clients without server-side validation. | ||
|
|
||
| - Cache [access tokens](/docs/secure/tokens/access-tokens) since they can be reused until they expire. | ||
|
|
||
| - Batch and minimize [metadata updates](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions#update-the-session-with-metadata). Avoid frequent metadata updates. | ||
|
|
||
|
|
||
| ## Limitations | ||
|
|
||
| - [Password reset](/docs/customize/actions/explore-triggers/password-reset-triggers#password-reset-triggers) flows are not supported by anonymous sessions. | ||
| - [Device Code](/docs/get-started/authentication-and-authorization-flow/device-authorization-flow) is not supported because the authentication request and the actual login happen on different devices. | ||
| - [Client-Initiated Backchannel Authentication (CIBA)](/docs/get-started/applications/configure-client-initiated-backchannel-authentication) is not supported because the authentication request and confirmation happen on different devices. | ||
| - [Custom token exchange](/docs/authenticate/custom-token-exchange/cte-example-use-cases) is not supported due to the nature of the transactions (for example, impersonation), which creates a likelihood of attributing anonymous data to the wrong user. | ||
| - [Refresh token exchange](/docs/secure/call-apis-on-users-behalf/token-vault/configure-token-vault#configure-token-exchange) is not supported by anonymous sessions because the user is already logged in if they had a refresh token. | ||
|
|
||
| ## Learn more | ||
|
|
||
| - [Configure Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions) Learn how to configure anonymous sessions. | ||
| - [Anonymous Sessions Use Cases](/docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases) Learn about anonymous sessions use cases. | ||
161 changes: 161 additions & 0 deletions
161
.../docs/manage-users/sessions/anonymous-sessions/anonymous-sessions-use-cases.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| --- | ||
| title: Anonymous Sessions Use Cases | ||
| description: Learn about anonymous sessions use cases with Actions. | ||
| sidebarTitle: Use Cases | ||
|
BcnCarlos marked this conversation as resolved.
|
||
| --- | ||
|
|
||
| import { ReleaseStageNotice } from "/snippets/ReleaseStageNotice.jsx" | ||
|
|
||
| <ReleaseStageNotice | ||
| feature="Anonymous Sessions" | ||
| stage="beta" | ||
| terms="true" | ||
| contact="Auth0 Support" | ||
| /> | ||
|
|
||
| When a user authenticates in your application, anonymous sessions and [Actions](/docs/customize/actions/actions-overview) allow you to transfer anonymous session data, such as shopping cart contents, preferences, and browsing history, to their authenticated user profile. | ||
|
|
||
| You can reference the `event.anonymous_session` object in Actions: | ||
|
|
||
| ```typescript theme={null} | ||
| { | ||
| user_id: string; // anonymous user id | ||
| session_id: string; // anonymous session token id | ||
| created_at: number; // anonymous session creation timestamp | ||
| expires_at: number; // anonymous session expiration timestamp | ||
| metadata: { // anonymous session metadata object | ||
| [key: string]: string | ||
| }; | ||
| } | ||
| ``` | ||
|
|
||
| ## Anonymous sessions and Actions use cases | ||
|
|
||
| ### Save anonymous session metadata to a new user | ||
|
|
||
| You can use a [`pre-user-registration`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/pre-user-registration-trigger) Action trigger to copy anonymous metadata into the new user profile when they sign up: | ||
|
|
||
| ```javascript wrap lines | ||
| exports.onExecutePreUserRegistration = async (event, api) => { | ||
| if (event.anonymous_session) { | ||
| // Store reference to the anonymous session | ||
| api.user.setAppMetadata( | ||
| 'linked_anonymous_id', | ||
| event.anonymous_session.user_id | ||
| ); | ||
|
|
||
| // Migrate cart data | ||
| if (event.anonymous_session.metadata.cart) { | ||
| api.user.setAppMetadata( | ||
| 'migrated_cart', | ||
| event.anonymous_session.metadata.cart | ||
| ); | ||
| } | ||
|
|
||
| // Copy preferences to user metadata | ||
| if (event.anonymous_session.metadata.preferences) { | ||
| api.user.setUserMetadata( | ||
| 'preferences', | ||
| event.anonymous_session.metadata.preferences | ||
| ); | ||
| } | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| ### Save anonymous session metadata to an existing user | ||
|
|
||
| You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to save anonymous metadata to existing users when they log in: | ||
|
|
||
| ```javascript wrap lines | ||
| exports.onExecutePostLogin = async (event, api) => { | ||
| if (event.anonymous_session) { | ||
| // Store last anonymous session reference | ||
| api.user.setAppMetadata( | ||
| 'last_anonymous_session', | ||
| event.anonymous_session.user_id | ||
| ); | ||
|
|
||
| // Add anonymous cart to access token for your API to process | ||
| api.accessToken.setCustomClaim( | ||
| 'anonymous_cart', | ||
| event.anonymous_session.metadata.cart | ||
| ); | ||
|
|
||
| // Track all linked sessions (optional) | ||
| const linkedSessions = | ||
| event.user.app_metadata?.linked_sessions || []; | ||
| if (!linkedSessions.includes(event.anonymous_session.user_id)) { | ||
| api.user.setAppMetadata('linked_sessions', [ | ||
| ...linkedSessions, | ||
| event.anonymous_session.user_id, | ||
| ]); | ||
| } | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| ### Merge user metadata with anonymous metadata | ||
|
|
||
| You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to merge anonymous metadata to an existing user metadata, such as a cart information, when they log in: | ||
|
|
||
| ```javascript wrap lines | ||
| exports.onExecutePostLogin = async (event, api) => { | ||
| if (!event.anonymous_session?.metadata?.cart) { | ||
| return; // No anonymous cart to merge | ||
| } | ||
|
|
||
| const anonymousCart = event.anonymous_session.metadata.cart; | ||
| const existingCart = event.user.app_metadata?.cart || { items: [] }; | ||
|
|
||
| // Merge cart items, combining quantities for matching SKUs | ||
| const mergedItems = [...existingCart.items]; | ||
| for (const anonItem of anonymousCart.items) { | ||
| const existingIndex = mergedItems.findIndex( | ||
| (item) => item.sku === anonItem.sku | ||
| ); | ||
| if (existingIndex >= 0) { | ||
| mergedItems[existingIndex].qty += anonItem.qty; | ||
| } else { | ||
| mergedItems.push(anonItem); | ||
| } | ||
| } | ||
|
|
||
| api.user.setAppMetadata('cart', { items: mergedItems }); | ||
| api.accessToken.setCustomClaim('cart', { items: mergedItems }); | ||
| }; | ||
| ``` | ||
|
|
||
| ### Handle multiple anonymous sessions | ||
|
|
||
| You can use a [`post-login`](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger) Action trigger to manage anonymous session metadata from different devices, when the user logs in: | ||
|
|
||
| ```javascript wrap lines | ||
| exports.onExecutePostLogin = async (event, api) => { | ||
| if (!event.anonymous_session) return; | ||
|
|
||
| const linkedSessions = | ||
| event.user.app_metadata?.linked_sessions || []; | ||
|
|
||
| // Option 1: Keep all linked sessions | ||
| api.user.setAppMetadata('linked_sessions', [ | ||
| ...linkedSessions, | ||
| { | ||
| user_id: event.anonymous_session.user_id, | ||
| linked_at: new Date().toISOString(), | ||
| device: event.request.user_agent, | ||
| }, | ||
| ]); | ||
|
|
||
| // Option 2: Keep only the most recent | ||
| api.user.setAppMetadata('last_anonymous_session', { | ||
| user_id: event.anonymous_session.user_id, | ||
| metadata: event.anonymous_session.metadata, | ||
| }); | ||
| }; | ||
| ``` | ||
|
|
||
| ## Learn more | ||
|
BcnCarlos marked this conversation as resolved.
|
||
|
|
||
| - [Configure Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions/configure-anonymous-sessions) Learn how to configure anonymous sessions. | ||
| - [Anonymous Sessions](/docs/manage-users/sessions/anonymous-sessions) Learn about anonymous sessions. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.