Overview
Sessions provide a way to uniquely identify users on your application and maintain useful state information. A session allows you to detect whether a user is logged in or not, determine access privileges, enable personalized experiences, and build insights from user interactions.
Stytch Member Sessions
In particular, Stytch Sessions in B2B are initiated with any successful authentication calls to start an authentication flow - namely with Email Magic Links, OAuth, Single Sign On, or Passwords. These methods generate a newly minted Member Session object in the response, as shown in the example below.
It contains several useful attributes about the Member’s logged in state, such as the member_id, organization_id, and email_address that act as unique identifiers passed to the API. You can choose to store these identifiers as part of your application logic.
{
"member_session": {
"member_session_id": "session-test-fe6c042b-6286-479f-8a4f-b046a6c46509",
"member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
"started_at": "2023-01-09T07:41:52Z",
"last_accessed_at": "2023-01-09T07:41:52Z",
"expires_at": "2021-08-10T07:41:52Z",
"authentication_factors": [
{
"delivery_method": "email",
"email_factor": {
"email_address": "sandbox@stytch.com",
"email_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
},
"last_authenticated_at": "2023-01-09T07:41:52Z",
"created_at": "2023-01-09T07:41:52Z",
"updated_at": "2023-01-09T07:41:52Z",
"sequence_order": "PRIMARY",
"type": "magic_link"
}
],
"custom_claims": {
"claim1": "value1",
"claim2": "value2"
},
"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
"roles": ["stytch_member", "editor"]
}
}
How to Use Member Sessions
Sessions at Stytch are stored as session tokens and JSON Web Tokens (JWTs). Managing these Sessions plays a crucial role in authenticating and authorizing requests between your client and server.
Beginning a Session
You can begin a Session upon a successful Authenticate call, such as calling the Authenticate Magic Link endpoint. You can choose to include a session_duration_minutes parameter to create a Session with the specified lifetime. Sessions can be between 5 minutes and 527040 minutes (366 days) long. The response fields will include values for member_session, session_token, and session_jwt.
If left empty, the default length for session_duration_minutes will be set to 60.
The code sample below is an example response from a Stytch successful authentication. Stytch Member Sessions are identified via the session_token and session_jwt fields. These identifiers should be forwarded and stored on the client-side (usually as a browser cookie).
{
"status_code": 200,
"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
"member_session": {...},
"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
"session_jwt": "",
"member": {...},
"organization": {...}
}
Authenticating a Session
With these identifiers, you want to ensure the Session is valid via the Authenticate Session endpoint on each request that requires authorization. This is true for simpler scenarios, such as automatically logging a user in, to more complex scenarios, such as performing an authorization check to access a sensitive resource.
If the Member's Session is still valid, use the member_id to identify the Member and send the session_token or session_jwt to the Member in a Session cookie.
If it isn’t valid, clear the Session cookie to log the end user out and do not process the request. The Authenticate Session endpoint always returns the session_token or session_jwt for convenience. We recommend following OWASP's guide on cookie storage.
Exchanging Sessions between Organizations
Stytch allows Members to exchange their active Sessions for new Sessions in other Organizations. By calling the Exchange Sessions endpoint, Members can switch between their Organizations without needing to log out and log back in to each Organization individually.
Provide the target organization_id and either the session_token or session_jwt of the active Session to be exchanged.
curl --request POST \
--url https://test.stytch.com/v1/b2b/sessions/exchange \
-u '{PROJECT_ID}:{SECRET}' \
-H 'Content-Type: application/json' \
-d '{
"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
}'
Extending or revoking a Session
To extend a Session’s lifetime, call the Authenticate Session endpoint with the session_duration_minutes parameter. The Session will be set to expire that many minutes from now.
To revoke a Session, call the Revoke Session endpoint with the member_session_id, session_token, or session_jwt (whichever is most convenient).
We recommend showing the end user a list of all their active Sessions so they can revoke any they don’t recognize by IP address and/or User-Agent. To attach values to Sessions, add them to the session_custom_claims parameter in endpoints like the Authenticate Session endpoint and Authenticate Magic Link endpoint.
Intermediate Sessions
An Intermediate Session Token (IST) is a type of session token that represents an Intermediate Session. This session represents a temporary state of “being authenticated”. It must be exchanged for a fully realized Member Session upon the user: 1) completing the entire authentication and 2) selecting or creating an Organization. Since an Organization isn’t available until after a Member Session is created, Intermediate Sessions aren't associated with a specific Organization - only Member Sessions are.
Additionally, ISTs are valid for 10 minutes. If they're not exchanged for a Member Session within that time period, the user must restart the authentication process.
Intermediate Sessions and ISTs in Stytch B2B are used in both the Discovery and MFA flows. We will dive into each of the flows in this section.
Discovery Flows
In Stytch B2B, there are two types of authentication flows: Discovery and Organization, which is discussed more in detail here. At a high level, the Organization flow allows users to log in directly into a specific Organization, while the Discovery flow allows users to "discover" all of the Organizations that they have access to, or create a new one.
ISTs are created during the Discovery flow from the following Authenticate methods:
- OAuth Authenticate
- Email Magic Links Authenticate
Upon success, these methods return an intermediate_session_token, which must be passed to the Exchange Intermediate Session endpoint. If MFA is not required, the Exchange method returns a member_authenticated = true with the member_session object, sesssion_token, and session_jwt. The session information then can be stored in the browser’s cookies for tracking Member sessions.
MFA Flows
An MFA flow involves two authentication steps: Primary and Secondary authentication. ISTs are created as an intermediary session between the Primary and Secondary authentication when MFA is required.
When MFA is optional, it is an additional flow that happens after a Member is successfully logged in and Stytch uses their Member Session as opposed to an Intermediate Session. The rest of the section will cover scenarios when MFA is required.
Note that MFA is supported in both Discovery and Organization flows.
Discovery Flow
Upon completion of the Primary authentication, if MFA is required, the intermediate_session_token that is passed to the Exchange Intermediate Session endpoint will not consumed and simply returned back in the response. Additionally, the method returns a member_authenticated = false with no additional session information. This is because the IST must be passed to a Secondary Authenticate method for the Member Session exchange to occur.
Organization Flow
For Organization flows, ISTs are created from the following Primary Authenticate methods:
- OAuth Authenticate
- Email Magic Links Authenticate
- SSO Authenticate
- Passwords Authenticate
Secondary Authentication
The accepted Secondary authentication methods are:
- SMS One-Time Passcodes (OTP) Authenticate
- Time-based One-Time Passcodes (TOTP) Authenticate
- Recovery Codes Recover
The intermediate_session_token must be passed as a parameter to complete the MFA. If successful, these methods will return the member_session object, session_token, and session_jwt. The session information then can be stored in the browser’s cookies for tracking Member sessions.
Code Examples
Creating a Session after login that lasts 30 days
Create a Session that expires 30 days (43200 minutes) after the initial login.
curl --request POST \
--url https://test.stytch.com/v1/b2b/magic_links/authenticate \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"magic_links_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
"session_duration_minutes": 43200
}'
curl --request POST \
--url https://test.stytch.com/b2b/sessions/authenticate \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
}'
Extending a Session by 30 days
Every time a Member's Session is authenticated, extend it for another 30 days (43200 minutes). This means that if the Session continues to be successfully authenticated at least once every 30 days the end user will remain logged in indefinitely, unless the Session is explicitly revoked.
curl --request POST \
--url https://test.stytch.com/v1/b2b/magic_links/authenticate \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
"session_duration_minutes": 43200
}'
curl --request POST \
--url https://test.stytch.com/v1/b2b/sessions/authenticate \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
"session_duration_minutes": 43200
}'
Revoking a Member's Session
curl --request POST \
--url https://test.stytch.com/v1/b2b/sessions/revoke \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"member_session_id": "session-test-fe6c042b-6286-479f-8a4f-b046a6c46509"
}'
Logging out a Member from all Sessions
curl --request POST \
--url https://test.stytch.com/v1/b2b/sessions/revoke \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f"
}'