From 46ad0c11e87745b937859d7422dc02aa16a8632b Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Tue, 19 Dec 2023 17:07:58 +0000 Subject: [PATCH 01/43] moving how clerk works to concepts section --- docs/concepts/how-clerk-works.mdx | 98 +++++++++++++++++++++++++++++++ docs/manifest.json | 10 ++++ 2 files changed, 108 insertions(+) create mode 100644 docs/concepts/how-clerk-works.mdx diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx new file mode 100644 index 0000000000..de580518f3 --- /dev/null +++ b/docs/concepts/how-clerk-works.mdx @@ -0,0 +1,98 @@ +--- +title: How Clerk works +description: +type: conceptual +--- + +# How Clerk works + +## Development and production instances + +Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. For more details on Clerk internals please review the following sections. + + +Never use a development instance in a production environment. Development instances don’t have the same strong security guarantees. + + +## Main objects + +Clerk uses five main objects: + +### [Client](/docs/references/javascript/client#client) + +A client represents the current device or software accessing an application such as your web browser, native application, Chrome Extension, or Electron app. + +### [Session](/docs/references/javascript/session) + +A session is a secure representation of the authentication state of the current user. Each client can hold multiple sessions on the same device. This is identical to how Gmail works in a browser. + +### [User](/docs/users/overview) + +A user represents the current user of the session. The object holds all the basic user information e.g. name, email addresses, phone numbers, etc… including their public, private, and unsafe metadata. + +### [Organization](/docs/organizations/roles-permissionsn) + +An organization represents the current organization of the session. Users can belong to many organizations. One of them will be the current organization of the session. + +### [Roles](/docs/organizations/roles-permissions) + +A user belongs to an organization with a role that defines their permissions. Currently, Clerk supports two roles, `org:admin` and `org:member`. + +## Clerk Frontend API (FAPI) + +Every Clerk development and production instance has a dedicated [Frontend API](https://clerk.com/docs/reference/frontend-api). This is the authentication, session, user & organization management API you or your users will interact with within the web browser, native application, Chrome extension, or Electron app. + +Clerk assigns a unique random API URL such as `https://delicate-wahoo-73.accounts.dev/sign-in` to each development instance. For production instances, the Frontend API lives at `https://clerk.[your-domain.com]`. + +### How it works + +Clerk's Frontend API is responsible for maintaining the authentication state of the current client (browser or native application). Based on the authentication's state (`signed-in`, `signed-out`, `unknown`) it mints a short-lived session [JSON Web Token (JWT)](/docs/backend-requests/making/jwt-templates) for the current user and session to be used by the host application that is secured by Clerk. The session JWT is stored in a cookie or can be retrieved at any time via the [`getToken()`](/docs/references/javascript/session#get-token) method. + +### Clerk cookies + +Clerk Frontend API uses two cookies for production instances: + +1. `__client` cookie: This cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It’s HTTP only, first-party and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. +2. `__session` cookie: This cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR). + +### The Interstitial page for SSR + +Clerk is a frontend-first authentication solution. [ClerkJS](/docs/references/javascript/overview) is responsible for ensuring that a fresh, valid `__session` cookie is always available to be used for CSR, SSR, and API requests by the host application. + +In SSR, it is common that the latest `__session` cookie might have expired if the user hasn’t visited the page for more than a minute. Using the `__session` cookie in the first doc-type request will result in unauthenticated request although the user is still signed-in in Clerk Frontend API. + +To address this issue, Clerk SDKs in SSR frameworks such as Next.js, Remix, or Gatsby, use the Interstitial page mechanism that intercepts such requests, gives an opportunity to ClerkJS to refresh the `__session` cookie, and replays the original requests. The Interstitial page runs at Edge for maximum performance. + +### Client piggybacking + +Every Frontend API request except from `/v1/client/sessions/:id/tokens` that refreshes the Clerk session tokens, returns a response payload that contains two top level keys + +```json +{ + client: ..., + response: ... +} +``` + +The response key contains the resource or resources of each endpoint. The client key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users and organization data for the current device (see Clerk Main Objects section). + +This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the React hooks and the Components. It is a best-effort way for the backend to update the frontend state on every Frontend API request. + +Client piggybacking was a quick solution to address reactivity in the early days of Clerk but has the following issues: + +1. It’s a very large chunk of a tree-like state and doesn’t change often. +1. It’s hard to compute on the backend as it requires a lot of data from the database. The computation takes place on every request adding a significant overhead. +1. It’s best effort. +1. It’s not a two-way communication channel. + +There are couple of suggestions on how to address these issues. In [this Slack thread](https://clerkinc.slack.com/archives/C054QN7SPQS/p1689684241427859?thread_ts=1689664883.849839&cid=C054QN7SPQS) and [Notion document about reactivity](https://www.notion.so/4130017f492144448d1f7a1ad84a157c?pvs=21) you can also find more information about the future direction. + +### Clerk Frontend API for non-standard web browsers + +Clerk offers a seamless authentication solution for non-standard web browser environments such as React Native applications, Chrome Extensions, and hybrid apps in platforms like Capacitor.js or Electron. + +These platforms treat cookies differently than web browsers. As a result, ClerkJS should use the HTTP Authorization header instead of the `__client` cookie for secure communication with the Clerk Frontend API. To get the initial `__client` JWT, set the HTTP Authorization header to an empty string value `“”` and Clerk Frontend API will return the client JWT in the response. To achieve session persistence, the `__client` JWT should be stored in a secure storage provided by each platform and then it should be injected into every Clerk Frontend API request. + +## Clerk Backend API (BAPI) + +Clerk's [Backend API](https://clerk.com/docs/reference/backend-api) is a restful CRUD API for the server side. It allows a sudo-level management of all Clerk objects. \ No newline at end of file diff --git a/docs/manifest.json b/docs/manifest.json index da4acd6be9..e72cbe37eb 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -23,6 +23,16 @@ ["Fastify", "/quickstarts/fastify"] ] ], + [ + { + "title": "Concepts", + "icon": "lightning-bolt", + "root": "concepts" + }, + [ + ["How Clerk Works", "/concepts/how-clerk-works"] + ] + ], "---", [ { From b4387ff20c4f62410e3c0798b1fa5ec0e3a6546a Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Tue, 19 Dec 2023 17:13:26 +0000 Subject: [PATCH 02/43] fix lank --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index de580518f3..4a11fbdf8f 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -30,7 +30,7 @@ A session is a secure representation of the authentication state of the current A user represents the current user of the session. The object holds all the basic user information e.g. name, email addresses, phone numbers, etc… including their public, private, and unsafe metadata. -### [Organization](/docs/organizations/roles-permissionsn) +### [Organization](/docs/organizations/roles-permissions) An organization represents the current organization of the session. Users can belong to many organizations. One of them will be the current organization of the session. From 69e26279c37cddf168277839890d9827981aa07c Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Tue, 19 Dec 2023 18:41:02 +0000 Subject: [PATCH 03/43] remove slack and notion references under piggybacking --- docs/concepts/how-clerk-works.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 4a11fbdf8f..6500b7bdc9 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -74,19 +74,17 @@ Every Frontend API request except from `/v1/client/sessions/:id/tokens` that ref } ``` -The response key contains the resource or resources of each endpoint. The client key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users and organization data for the current device (see Clerk Main Objects section). +The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users and organization data for the current device (see [Main Objects](#main-objects) section). This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the React hooks and the Components. It is a best-effort way for the backend to update the frontend state on every Frontend API request. -Client piggybacking was a quick solution to address reactivity in the early days of Clerk but has the following issues: +It's not recommended to use Client piggybacking because of the following issues: 1. It’s a very large chunk of a tree-like state and doesn’t change often. 1. It’s hard to compute on the backend as it requires a lot of data from the database. The computation takes place on every request adding a significant overhead. 1. It’s best effort. 1. It’s not a two-way communication channel. -There are couple of suggestions on how to address these issues. In [this Slack thread](https://clerkinc.slack.com/archives/C054QN7SPQS/p1689684241427859?thread_ts=1689664883.849839&cid=C054QN7SPQS) and [Notion document about reactivity](https://www.notion.so/4130017f492144448d1f7a1ad84a157c?pvs=21) you can also find more information about the future direction. - ### Clerk Frontend API for non-standard web browsers Clerk offers a seamless authentication solution for non-standard web browser environments such as React Native applications, Chrome Extensions, and hybrid apps in platforms like Capacitor.js or Electron. From 333c047bc2a91cc63eb4de808d201f059fa3fb1e Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Wed, 20 Dec 2023 16:31:35 +0000 Subject: [PATCH 04/43] updating interstitial with handshake --- docs/concepts/how-clerk-works.mdx | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 6500b7bdc9..7abc105313 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -50,18 +50,26 @@ Clerk's Frontend API is responsible for maintaining the authentication state of ### Clerk cookies -Clerk Frontend API uses two cookies for production instances: +Clerk’s Frontend API uses two cookies for session management in production instances: -1. `__client` cookie: This cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It’s HTTP only, first-party and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. -2. `__session` cookie: This cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR). +* `__client` cookie: a long-lived session that is used to keep the the session JWT fresh by interacting with the Frontend API +* `__session` cookie: a short-lived session JWT to validate requests -### The Interstitial page for SSR +#### The `__client` cookie -Clerk is a frontend-first authentication solution. [ClerkJS](/docs/references/javascript/overview) is responsible for ensuring that a fresh, valid `__session` cookie is always available to be used for CSR, SSR, and API requests by the host application. +This cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It’s HTTP-only, first-party, and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. -In SSR, it is common that the latest `__session` cookie might have expired if the user hasn’t visited the page for more than a minute. Using the `__session` cookie in the first doc-type request will result in unauthenticated request although the user is still signed-in in Clerk Frontend API. +#### The `__session` cookie -To address this issue, Clerk SDKs in SSR frameworks such as Next.js, Remix, or Gatsby, use the Interstitial page mechanism that intercepts such requests, gives an opportunity to ClerkJS to refresh the `__session` cookie, and replays the original requests. The Interstitial page runs at Edge for maximum performance. +This cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR). + +If a `__session` cookie is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. + +### The client handshake + +Clerk uses a client handshake mechanism to resolve a request’s authentication state from `unknown` to `signed-in` or `signed-out`. + +With this handshake, Clerk can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially `unknown` state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. ### Client piggybacking From 46c931b262d76de68eb3c86480eaf95bb1180355 Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Wed, 20 Dec 2023 16:42:51 +0000 Subject: [PATCH 05/43] adding more about client handshake --- docs/concepts/client-handshake.mdx | 62 ++++++++++++++++++++++++++++++ docs/concepts/how-clerk-works.mdx | 8 ++-- docs/manifest.json | 3 +- 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 docs/concepts/client-handshake.mdx diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx new file mode 100644 index 0000000000..a21c754934 --- /dev/null +++ b/docs/concepts/client-handshake.mdx @@ -0,0 +1,62 @@ +--- +title: Client handshake +description: The Client Handshake is a mechanism that is used to resolve a request’s authentication state from “unknown” to definitively signed in or signed out. +type: conceptual +--- + +# The client handshake + +Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that is used to keep the the session JWT fresh by interacting with the Frontend API. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. + +With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. + +## Handshake flow + +The handshake mechanism operates by way of a redirect from the host application to a FAPI endpoint: + +1. Request is made to an application using Clerk +2. Clerk SDK determines the authentication state of the request (`signed-in`, `signed-out`, or `handshake`). +3. If authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake` +4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response + 1. If the session is active, a fresh session JWT cookie is returned + 2. If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out +5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development) or as a cookie (production) +6. The handshake payload is parsed and `Set-Cookie` headers are set on the response +7. If an updated session JWT is returned, the JWT is verified + 1. If successful, the request is treated as signed in +8. If an updated session JWT is not returned, the request is treated as signed out + +## Scenarios that trigger a handshake + + +A handshake is only triggered If a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. + + +1. Development instance and a dev browser is detected in URL **[URL-based session sync]** +2. Production instance and request is being made to a satellite application **[satellite needs sync]** +3. Has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) **[session token without client UAT]** +4. Has active client (`__client_uat` > 0) but no session token **[client UAT without session token]** +5. Client UAT is more recent than current session token issued at (`__client_uat` > `sessionToken.iat`) **[session token outdated]** +6. Session token exists but is expired **[session token expired]** +7. Session token exists but is not active yet **[session token not active yet]** + +## Handshake architecture + +The handshake flow is composed of two main pieces: + +1. The FAPI [`/client/handshake` endpoint](https://github.com/clerk/clerk_go/blob/main/api/fapi/v1/router/router.go#L223) +2. The [`@clerk/backend` `authenticateRequest()` method](https://github.com/clerk/javascript/blob/main/packages/backend/src/tokens/request.ts#L74) + +### `/client/handshake` endpoint + +The endpoint should always result in a redirect back to the provided `redirect_url`. Along with the response, a **[handshake payload](#handshake-payload)** is returned. The handshake endpoint also handles multi-domain syncing between a satellite and a primary domain. If possible, the handshake will return a refreshed session token, as well as updated dev browser (`__clerk_db_jwt`) and Client UAT (`__client_uat`) cookies. + +### `@clerk/backend` method + +The `authenticateRequest()` method from the backend package primarily handles determining the authentication state of a given `Request` object. If the request state is determined to be `handshake`, the method returns returns headers to redirect to the handshake endpoint. These headers must then be set on the response returned by the SDK. + +On redirect back to an application from the handshake endpoint, `authenticateRequest()` will run again and parse the handshake payload. Based on the contents of the payload, the request is determined to definitively be `signed-in` or `signed-out` and handled accordingly. The cookie directives from the handshake payload are set as `Set-Cookie` headers on the final response. + +### Handshake payload + +The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. \ No newline at end of file diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 7abc105313..b1ac4b0fd7 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -46,7 +46,7 @@ Clerk assigns a unique random API URL such as `https://delicate-wahoo-73.account ### How it works -Clerk's Frontend API is responsible for maintaining the authentication state of the current client (browser or native application). Based on the authentication's state (`signed-in`, `signed-out`, `unknown`) it mints a short-lived session [JSON Web Token (JWT)](/docs/backend-requests/making/jwt-templates) for the current user and session to be used by the host application that is secured by Clerk. The session JWT is stored in a cookie or can be retrieved at any time via the [`getToken()`](/docs/references/javascript/session#get-token) method. +Clerk's Frontend API is responsible for maintaining the authentication state of the current client (browser or native application). Based on the authentication's state (`signed-in`, `signed-out`, `handshake`) it mints a short-lived session [JSON Web Token (JWT)](/docs/backend-requests/making/jwt-templates) for the current user and session to be used by the host application that is secured by Clerk. The session JWT is stored in a cookie or can be retrieved at any time via the [`getToken()`](/docs/references/javascript/session#get-token) method. ### Clerk cookies @@ -67,9 +67,11 @@ If a `__session` cookie is expired on a request to an application’s backend, t ### The client handshake -Clerk uses a client handshake mechanism to resolve a request’s authentication state from `unknown` to `signed-in` or `signed-out`. +Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. -With this handshake, Clerk can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially `unknown` state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. +With this handshake, Clerk can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially unknown state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. + +Learn more about [how Clerk's client handshake works in this deep dive](/docs/concepts/client-handshake). ### Client piggybacking diff --git a/docs/manifest.json b/docs/manifest.json index 5bbce80e13..5928bb13b5 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -30,7 +30,8 @@ "root": "concepts" }, [ - ["How Clerk Works", "/concepts/how-clerk-works"] + ["How Clerk Works", "/concepts/how-clerk-works"], + ["Client Handshake", "/concepts/client-handshake"] ] ], "---", From 680799c00d8502a2650b61cefd998d1162a0ff1b Mon Sep 17 00:00:00 2001 From: R L Nabors Date: Wed, 20 Dec 2023 18:36:20 +0000 Subject: [PATCH 06/43] Update docs/concepts/how-clerk-works.mdx Co-authored-by: Kyle MacDonald --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index b1ac4b0fd7..8cc2fcc8aa 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -8,7 +8,7 @@ type: conceptual ## Development and production instances -Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. For more details on Clerk internals please review the following sections. +Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. Development instances contain certain trade-offs meant to support ease of active development. For more details on the differences, read the [Instances / Environments](/docs/deployments/environments) doc. Never use a development instance in a production environment. Development instances don’t have the same strong security guarantees. From 80ec9709bce2fdb4ac9c2d75ec9e235790d3c05e Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Fri, 22 Dec 2023 10:29:06 +0000 Subject: [PATCH 07/43] incorporating Sok's feedback --- docs/concepts/how-clerk-works.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 8cc2fcc8aa..2c9280dc92 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -8,10 +8,10 @@ type: conceptual ## Development and production instances -Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. Development instances contain certain trade-offs meant to support ease of active development. For more details on the differences, read the [Instances / Environments](/docs/deployments/environments) doc. +Clerk provices both development and production environments for your app. Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. Development instances contain certain trade-offs meant to support ease of active development. -Never use a development instance in a production environment. Development instances don’t have the same strong security guarantees. +Never use a development instance in a production environment. Development instances don’t have strong security guarantees. ## Main objects @@ -20,7 +20,7 @@ Clerk uses five main objects: ### [Client](/docs/references/javascript/client#client) -A client represents the current device or software accessing an application such as your web browser, native application, Chrome Extension, or Electron app. +A client represents the current device or software accessing an application such as your web browser, native application for Android or iOS, Chrome Extension, or Electron app. ### [Session](/docs/references/javascript/session) @@ -52,8 +52,8 @@ Clerk's Frontend API is responsible for maintaining the authentication state of Clerk’s Frontend API uses two cookies for session management in production instances: -* `__client` cookie: a long-lived session that is used to keep the the session JWT fresh by interacting with the Frontend API -* `__session` cookie: a short-lived session JWT to validate requests +* `__client` cookie: a long-lived session that is used to keep the the session JWT fresh by interacting with the Frontend API. +* `__session` cookie: a short-lived session JWT to validate requests on your application or your API. #### The `__client` cookie @@ -61,9 +61,9 @@ This cookie is set on Clerk Frontend API (for example `https://clerk.`). It’s a JS cookie, it’s secure, and contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR). +This cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user, and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR), ensuring a fresh session is always available. -If a `__session` cookie is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. +However, if a `__session` cookie is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. ### The client handshake @@ -99,7 +99,7 @@ It's not recommended to use Client piggybacking because of the following issues: Clerk offers a seamless authentication solution for non-standard web browser environments such as React Native applications, Chrome Extensions, and hybrid apps in platforms like Capacitor.js or Electron. -These platforms treat cookies differently than web browsers. As a result, ClerkJS should use the HTTP Authorization header instead of the `__client` cookie for secure communication with the Clerk Frontend API. To get the initial `__client` JWT, set the HTTP Authorization header to an empty string value `“”` and Clerk Frontend API will return the client JWT in the response. To achieve session persistence, the `__client` JWT should be stored in a secure storage provided by each platform and then it should be injected into every Clerk Frontend API request. +These platforms treat cookies differently than web browsers. As a result, ClerkJS should use the HTTP Authorization header instead of the `__client` cookie for secure communication with the Clerk Frontend API. To achieve session persistence, the `__client` JWT should be stored in a secure storage provided by each platform and then it should be injected into every Clerk Frontend API request. ## Clerk Backend API (BAPI) From 6009e4dce209e50d766c84e961360cd31fa1505c Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Fri, 22 Dec 2023 10:31:48 +0000 Subject: [PATCH 08/43] fix manifest --- docs/manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/manifest.json b/docs/manifest.json index 5fedc2ec0a..6f27bba51e 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -32,6 +32,7 @@ [ ["How Clerk Works", "/concepts/how-clerk-works"], ["Client Handshake", "/concepts/client-handshake"] + ] ], [ { From 158443c9674d80c82bad5d69f27168dda25e3dc4 Mon Sep 17 00:00:00 2001 From: R L Nabors Date: Fri, 22 Dec 2023 14:50:15 +0000 Subject: [PATCH 09/43] Update docs/concepts/client-handshake.mdx Co-authored-by: Sokratis Vidros --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index a21c754934..89b219b6a9 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -6,7 +6,7 @@ type: conceptual # The client handshake -Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that is used to keep the the session JWT fresh by interacting with the Frontend API. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. +Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. From 0d91e7c306d74e9ed7796471ac86dd0fa5824f28 Mon Sep 17 00:00:00 2001 From: R L Nabors Date: Fri, 22 Dec 2023 14:50:39 +0000 Subject: [PATCH 10/43] Update docs/concepts/client-handshake.mdx Co-authored-by: Sokratis Vidros --- docs/concepts/client-handshake.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 89b219b6a9..45ccc634b2 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -10,6 +10,8 @@ Clerk uses a client handshake mechanism to resolve a request’s authentication With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. +The resolution is fast and shouldn't be noticeable to the end user. + ## Handshake flow The handshake mechanism operates by way of a redirect from the host application to a FAPI endpoint: From 876c4cf46031942f6fcccc90b7b09f0acf3357ce Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Fri, 22 Dec 2023 14:56:55 +0000 Subject: [PATCH 11/43] Removing references to endpoint --- docs/concepts/client-handshake.mdx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 45ccc634b2..5ae214f6d5 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -46,12 +46,8 @@ A handshake is only triggered If a request is determined to be a document reques The handshake flow is composed of two main pieces: -1. The FAPI [`/client/handshake` endpoint](https://github.com/clerk/clerk_go/blob/main/api/fapi/v1/router/router.go#L223) -2. The [`@clerk/backend` `authenticateRequest()` method](https://github.com/clerk/javascript/blob/main/packages/backend/src/tokens/request.ts#L74) - -### `/client/handshake` endpoint - -The endpoint should always result in a redirect back to the provided `redirect_url`. Along with the response, a **[handshake payload](#handshake-payload)** is returned. The handshake endpoint also handles multi-domain syncing between a satellite and a primary domain. If possible, the handshake will return a refreshed session token, as well as updated dev browser (`__clerk_db_jwt`) and Client UAT (`__client_uat`) cookies. +1. The FAPI `/client/handshake` endpoint +2. The `@clerk/backend` `authenticateRequest()` method ### `@clerk/backend` method From e0aeb3e2ccc53279bd80b2ccf3e89872308a90c3 Mon Sep 17 00:00:00 2001 From: Rachel Lee Nabors Date: Fri, 22 Dec 2023 14:57:57 +0000 Subject: [PATCH 12/43] remove information about the backend auth req --- docs/concepts/client-handshake.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 5ae214f6d5..1d9fd0f3b2 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -49,12 +49,6 @@ The handshake flow is composed of two main pieces: 1. The FAPI `/client/handshake` endpoint 2. The `@clerk/backend` `authenticateRequest()` method -### `@clerk/backend` method - -The `authenticateRequest()` method from the backend package primarily handles determining the authentication state of a given `Request` object. If the request state is determined to be `handshake`, the method returns returns headers to redirect to the handshake endpoint. These headers must then be set on the response returned by the SDK. - -On redirect back to an application from the handshake endpoint, `authenticateRequest()` will run again and parse the handshake payload. Based on the contents of the payload, the request is determined to definitively be `signed-in` or `signed-out` and handled accordingly. The cookie directives from the handshake payload are set as `Set-Cookie` headers on the final response. - ### Handshake payload The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. \ No newline at end of file From 3c1a09f3add7fc82d0f1229f73ab637f055c6162 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:20:32 -0500 Subject: [PATCH 13/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 1d9fd0f3b2..92f732408d 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -1,6 +1,6 @@ --- title: Client handshake -description: The Client Handshake is a mechanism that is used to resolve a request’s authentication state from “unknown” to definitively signed in or signed out. +description: The client handshake is a mechanism that is used to resolve a request’s authentication state from “unknown” to definitively signed in or signed out. type: conceptual --- From 1bdf9e4b39931344c051716c668c58696b48174e Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:20:40 -0500 Subject: [PATCH 14/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 92f732408d..15f3b32775 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -22,7 +22,7 @@ The handshake mechanism operates by way of a redirect from the host application 4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response 1. If the session is active, a fresh session JWT cookie is returned 2. If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out -5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development) or as a cookie (production) +5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development instances) or as a cookie (production instances). 6. The handshake payload is parsed and `Set-Cookie` headers are set on the response 7. If an updated session JWT is returned, the JWT is verified 1. If successful, the request is treated as signed in From 03f80175b456e13f1451a0ff422beb838e73600f Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:20:44 -0500 Subject: [PATCH 15/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 15f3b32775..fb0cef4e87 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -16,7 +16,7 @@ The resolution is fast and shouldn't be noticeable to the end user. The handshake mechanism operates by way of a redirect from the host application to a FAPI endpoint: -1. Request is made to an application using Clerk +1. A request is made to an application using Clerk. 2. Clerk SDK determines the authentication state of the request (`signed-in`, `signed-out`, or `handshake`). 3. If authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake` 4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response From e502c7374c4653c9447886afbba6a9eb979d2ed9 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:20:49 -0500 Subject: [PATCH 16/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index fb0cef4e87..ff093ce82f 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -18,7 +18,7 @@ The handshake mechanism operates by way of a redirect from the host application 1. A request is made to an application using Clerk. 2. Clerk SDK determines the authentication state of the request (`signed-in`, `signed-out`, or `handshake`). -3. If authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake` +3. If the authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake`. 4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response 1. If the session is active, a fresh session JWT cookie is returned 2. If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out From 3cf1f09be3124f5bb1acade0f241f5c458664772 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:20:55 -0500 Subject: [PATCH 17/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index ff093ce82f..6eb4791564 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -19,7 +19,7 @@ The handshake mechanism operates by way of a redirect from the host application 1. A request is made to an application using Clerk. 2. Clerk SDK determines the authentication state of the request (`signed-in`, `signed-out`, or `handshake`). 3. If the authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake`. -4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response +4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response. 1. If the session is active, a fresh session JWT cookie is returned 2. If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out 5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development instances) or as a cookie (production instances). From 64be328c199a4fa54b474a4bb06c885b570b797f Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:04 -0500 Subject: [PATCH 18/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 6eb4791564..a8ef5ef545 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -20,8 +20,8 @@ The handshake mechanism operates by way of a redirect from the host application 2. Clerk SDK determines the authentication state of the request (`signed-in`, `signed-out`, or `handshake`). 3. If the authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake`. 4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response. - 1. If the session is active, a fresh session JWT cookie is returned - 2. If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out + - If the session is active, a fresh session JWT cookie is returned. + - If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out. 5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development instances) or as a cookie (production instances). 6. The handshake payload is parsed and `Set-Cookie` headers are set on the response 7. If an updated session JWT is returned, the JWT is verified From 2e5ebe84e8a18a2aae3a089ca3aa08bc6cc69e28 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:14 -0500 Subject: [PATCH 19/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index a8ef5ef545..c1b3d06ade 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -23,7 +23,7 @@ The handshake mechanism operates by way of a redirect from the host application - If the session is active, a fresh session JWT cookie is returned. - If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out. 5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development instances) or as a cookie (production instances). -6. The handshake payload is parsed and `Set-Cookie` headers are set on the response +6. The handshake payload is parsed and `Set-Cookie` headers are set on the response. 7. If an updated session JWT is returned, the JWT is verified 1. If successful, the request is treated as signed in 8. If an updated session JWT is not returned, the request is treated as signed out From 72b5695ee92abdc4f46b65f684cf47c15ecd8212 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:23 -0500 Subject: [PATCH 20/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index c1b3d06ade..30a0fa3e9b 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -24,9 +24,7 @@ The handshake mechanism operates by way of a redirect from the host application - If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out. 5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development instances) or as a cookie (production instances). 6. The handshake payload is parsed and `Set-Cookie` headers are set on the response. -7. If an updated session JWT is returned, the JWT is verified - 1. If successful, the request is treated as signed in -8. If an updated session JWT is not returned, the request is treated as signed out +7. If an updated session JWT is returned, the JWT is verified and then, if verification is successful, the request is treated as signed in. If an updated session JWT is not returned, the request is treated as signed out. ## Scenarios that trigger a handshake From ccd217a7105b8bc8645c9fee0bd6b081b3542d24 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:33 -0500 Subject: [PATCH 21/43] Update docs/concepts/client-handshake.mdx --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 30a0fa3e9b..8f1f9548bc 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -29,7 +29,7 @@ The handshake mechanism operates by way of a redirect from the host application ## Scenarios that trigger a handshake -A handshake is only triggered If a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. +A handshake is only triggered if a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. 1. Development instance and a dev browser is detected in URL **[URL-based session sync]** From b41d973e5c3b6facf34476c3796a9f1d7cc6d333 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:39 -0500 Subject: [PATCH 22/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 2c9280dc92..eb617f6d33 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -86,7 +86,7 @@ Every Frontend API request except from `/v1/client/sessions/:id/tokens` that ref The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users and organization data for the current device (see [Main Objects](#main-objects) section). -This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the React hooks and the Components. It is a best-effort way for the backend to update the frontend state on every Frontend API request. +This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the [React hooks](/docs/references/react/use-user), and [Clerk components](/docs/components/overview). It is a best-effort way for the backend to update the frontend state on every Frontend API request. It's not recommended to use Client piggybacking because of the following issues: From 45e914971bca93eaa9aec2924b71ef9bedf044dc Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:48 -0500 Subject: [PATCH 23/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index eb617f6d33..baa26787e5 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -28,7 +28,7 @@ A session is a secure representation of the authentication state of the current ### [User](/docs/users/overview) -A user represents the current user of the session. The object holds all the basic user information e.g. name, email addresses, phone numbers, etc… including their public, private, and unsafe metadata. +A user represents the current user of the session. The object holds all the basic user information such as the user's name, email addresses, and phone numbers, and including their public, private, and unsafe metadata. ### [Organization](/docs/organizations/roles-permissions) From 22c0607b941403753061bf64368f2509252d4d96 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:21:56 -0500 Subject: [PATCH 24/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index baa26787e5..45badbf938 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -44,7 +44,7 @@ Every Clerk development and production instance has a dedicated [Frontend API](h Clerk assigns a unique random API URL such as `https://delicate-wahoo-73.accounts.dev/sign-in` to each development instance. For production instances, the Frontend API lives at `https://clerk.[your-domain.com]`. -### How it works +### How Clerk's Frontend API works Clerk's Frontend API is responsible for maintaining the authentication state of the current client (browser or native application). Based on the authentication's state (`signed-in`, `signed-out`, `handshake`) it mints a short-lived session [JSON Web Token (JWT)](/docs/backend-requests/making/jwt-templates) for the current user and session to be used by the host application that is secured by Clerk. The session JWT is stored in a cookie or can be retrieved at any time via the [`getToken()`](/docs/references/javascript/session#get-token) method. From 16830152c6e072ce14e4f84a336f64147f149f09 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:04 -0500 Subject: [PATCH 25/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 45badbf938..a29bcb01ab 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -57,7 +57,7 @@ Clerk’s Frontend API uses two cookies for session management in production ins #### The `__client` cookie -This cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It’s HTTP-only, first-party, and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. +The `__client` cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It’s HTTP-only, first-party, and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. #### The `__session` cookie From fd40e0a7f56690a8597580ca04ed54314e3dd2f5 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:12 -0500 Subject: [PATCH 26/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index a29bcb01ab..02ce6ae9d0 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -61,7 +61,7 @@ The `__client` cookie is set on Clerk Frontend API (for example `https://clerk.< #### The `__session` cookie -This cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user, and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR), ensuring a fresh session is always available. +The `__session` cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and it contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user, and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR), ensuring a fresh session is always available. However, if a `__session` cookie is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. From 71805a3054f93f9f64d56078c3e4a523533eadef Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:21 -0500 Subject: [PATCH 27/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 02ce6ae9d0..5169f98356 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -71,7 +71,7 @@ Clerk uses a client handshake mechanism to resolve a request’s authentication With this handshake, Clerk can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially unknown state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. -Learn more about [how Clerk's client handshake works in this deep dive](/docs/concepts/client-handshake). +Learn more about [how Clerk's client handshake works.](/docs/concepts/client-handshake). ### Client piggybacking From 7bb4e382a48625a091cd252450f16b916dacce1e Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:30 -0500 Subject: [PATCH 28/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 5169f98356..87014220e1 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -75,7 +75,7 @@ Learn more about [how Clerk's client handshake works.](/docs/concepts/client-han ### Client piggybacking -Every Frontend API request except from `/v1/client/sessions/:id/tokens` that refreshes the Clerk session tokens, returns a response payload that contains two top level keys +Every Frontend API request returns a response payload that contains two top level keys: ```json { From 1e6b0d70f79b74b729409b2c0227716ac71b5a9d Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:37 -0500 Subject: [PATCH 29/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 87014220e1..4244736cb5 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -79,8 +79,8 @@ Every Frontend API request returns a response payload that contains two top leve ```json { - client: ..., - response: ... + "client": ..., + "response": ... } ``` From e808d32e638005dc2ac172a7037dbe593e2dde92 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:45 -0500 Subject: [PATCH 30/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 4244736cb5..333d7b0af7 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -84,7 +84,12 @@ Every Frontend API request returns a response payload that contains two top leve } ``` -The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users and organization data for the current device (see [Main Objects](#main-objects) section). + + The `/v1/client/sessions/:id/tokens` endpoint refreshes the Clerk session tokens and is an exception to this format. + + + +The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users, and organization data for the current device (see [Main Objects](#main-objects) section). This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the [React hooks](/docs/references/react/use-user), and [Clerk components](/docs/components/overview). It is a best-effort way for the backend to update the frontend state on every Frontend API request. From cac8bf948f809cf6defb8b58fb66c6eddae50a81 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:22:54 -0500 Subject: [PATCH 31/43] Update docs/concepts/how-clerk-works.mdx --- docs/concepts/how-clerk-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 333d7b0af7..74e863b973 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -96,7 +96,7 @@ This is effectively the necessary frontend state for ClerkJS and powers the JS S It's not recommended to use Client piggybacking because of the following issues: 1. It’s a very large chunk of a tree-like state and doesn’t change often. -1. It’s hard to compute on the backend as it requires a lot of data from the database. The computation takes place on every request adding a significant overhead. +1. It’s hard to compute on the backend as it requires a lot of data from the database. The computation takes place on every request, adding a significant overhead. 1. It’s best effort. 1. It’s not a two-way communication channel. From 2cd290e366b4fb94bb502a62b261d9ab5d1bbbfb Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:23:00 -0500 Subject: [PATCH 32/43] Update docs/manifest.json --- docs/manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/manifest.json b/docs/manifest.json index 6f27bba51e..87a69640ee 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -30,8 +30,8 @@ "root": "concepts" }, [ - ["How Clerk Works", "/concepts/how-clerk-works"], - ["Client Handshake", "/concepts/client-handshake"] + ["How Clerk works", "/concepts/how-clerk-works"], + ["Client handshake", "/concepts/client-handshake"] ] ], [ From 5b82fd514d0b80268207b5eebade121d4676690c Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:28:43 -0500 Subject: [PATCH 33/43] update sidenav icon; add meta desc for how clerk works --- docs/concepts/how-clerk-works.mdx | 2 +- docs/manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 74e863b973..e85266484e 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -1,6 +1,6 @@ --- title: How Clerk works -description: +description: Learn about the main concepts and objects that power Clerk's powerful authentication and user management system. type: conceptual --- diff --git a/docs/manifest.json b/docs/manifest.json index 87a69640ee..2c1f8f968f 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -26,7 +26,7 @@ [ { "title": "Concepts", - "icon": "lightning-bolt", + "icon": "lightbulb", "root": "concepts" }, [ From 4cdcdb20fdabac26e1411714e891873fd20003e4 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:50:02 -0500 Subject: [PATCH 34/43] add jwks link --- docs/concepts/client-handshake.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 8f1f9548bc..0977eaaf92 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -49,4 +49,6 @@ The handshake flow is composed of two main pieces: ### Handshake payload -The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. \ No newline at end of file +The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. + +To verify the handshake payload JWT, use the instance [public RSA key](https://clerk.com/docs/reference/frontend-api/tag/Well-Known#operation/GetJWKS). \ No newline at end of file From acddf449abca9b6ecc17f4cce27eaadf2d68682e Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:58:53 -0500 Subject: [PATCH 35/43] add fapi ref link for /client/handshake endpoint --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 0977eaaf92..abed8d0298 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -44,7 +44,7 @@ A handshake is only triggered if a request is determined to be a document reques The handshake flow is composed of two main pieces: -1. The FAPI `/client/handshake` endpoint +1. The FAPI [`/client/handshake` endpoint](https://clerk.com/docs/reference/frontend-api/tag/Client#operation/handshakeClient) 2. The `@clerk/backend` `authenticateRequest()` method ### Handshake payload From 067f5bfb282b5cda2a6dd77388f0d5559f4bcfac Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:00:03 -0500 Subject: [PATCH 36/43] remove braceketed phrases --- docs/concepts/client-handshake.mdx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index abed8d0298..223fe2450b 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -32,13 +32,14 @@ The handshake mechanism operates by way of a redirect from the host application A handshake is only triggered if a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. -1. Development instance and a dev browser is detected in URL **[URL-based session sync]** -2. Production instance and request is being made to a satellite application **[satellite needs sync]** -3. Has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) **[session token without client UAT]** -4. Has active client (`__client_uat` > 0) but no session token **[client UAT without session token]** -5. Client UAT is more recent than current session token issued at (`__client_uat` > `sessionToken.iat`) **[session token outdated]** -6. Session token exists but is expired **[session token expired]** -7. Session token exists but is not active yet **[session token not active yet]** +1. Development instance and a dev browser is detected in URL +[(URL-based session sync)](https://clerk.com/docs/upgrade-guides/url-based-session-syncing#url-based-session-syncing) +2. Production instance and request is being made to a satellite application +3. Has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) +4. Has active client (`__client_uat` > 0) but no session token +5. Client UAT is more recent than current session token issued at (`__client_uat` > `sessionToken.iat`) +6. Session token exists but is expired +7. Session token exists but is not active yet ## Handshake architecture From fe3d1bd8c8784b74378101920d9dadefdcc23618 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:00:30 -0500 Subject: [PATCH 37/43] Update docs/concepts/client-handshake.mdx Co-authored-by: Bryce Kalow --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 223fe2450b..0576b4e64f 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -6,7 +6,7 @@ type: conceptual # The client handshake -Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. +Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API (FAPI) while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. From 853a260d8b09a9ae7b670bee428e2bede2373f75 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:17:14 -0500 Subject: [PATCH 38/43] apply code review suggestions --- docs/concepts/client-handshake.mdx | 26 ++++++++++++++++---------- docs/concepts/how-clerk-works.mdx | 19 ++++++++++++------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 0576b4e64f..225b093829 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -6,7 +6,11 @@ type: conceptual # The client handshake -Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API (FAPI) while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. + + This flow applies only to website browser traffic and not native applications. + + +Clerk uses a mechanism called "the client handshake" to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API (FAPI) while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. @@ -18,38 +22,40 @@ The handshake mechanism operates by way of a redirect from the host application 1. A request is made to an application using Clerk. 2. Clerk SDK determines the authentication state of the request (`signed-in`, `signed-out`, or `handshake`). -3. If the authentication state is `handshake`, Clerk responds with a 307 redirect to the handshake endpoint: `fapi/v1/client/handshake`. +3. If the authentication state is `handshake`, Clerk SDK responds with a 307 redirect to the FAPI handshake endpoint: `https://clerk.your-domain.com/v1/client/handshake`. 4. The handshake endpoint gets information about the current session and returns a handshake payload. The encoded handshake payload contains a list of `Set-Cookie` header directives to be passed along with the final response. - If the session is active, a fresh session JWT cookie is returned. - If the session is inactive, the session JWT cookie is wiped and the request will be treated as signed out. 5. The handshake endpoint redirects back to the host application along with the handshake payload, encoded either in the URL (development instances) or as a cookie (production instances). -6. The handshake payload is parsed and `Set-Cookie` headers are set on the response. +6. The handshake payload is parsed by Clerk SDK and `Set-Cookie` headers are set on the response. 7. If an updated session JWT is returned, the JWT is verified and then, if verification is successful, the request is treated as signed in. If an updated session JWT is not returned, the request is treated as signed out. ## Scenarios that trigger a handshake -A handshake is only triggered if a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. + A handshake is only triggered if a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. 1. Development instance and a dev browser is detected in URL [(URL-based session sync)](https://clerk.com/docs/upgrade-guides/url-based-session-syncing#url-based-session-syncing) 2. Production instance and request is being made to a satellite application -3. Has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) -4. Has active client (`__client_uat` > 0) but no session token -5. Client UAT is more recent than current session token issued at (`__client_uat` > `sessionToken.iat`) -6. Session token exists but is expired -7. Session token exists but is not active yet +3. The current browser has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) +4. The current browser has an active client (`__client_uat` > 0) but no session token +5. The `client_uat` cookie indicating the latest timestamp a client was updated, is more recent than current session token issued at timestamp (`__client_uat` > `sessionToken.iat`) +6. The `__session` token cookie exists but is expired +7. The `__session` token cookie exists but is not active yet ## Handshake architecture The handshake flow is composed of two main pieces: 1. The FAPI [`/client/handshake` endpoint](https://clerk.com/docs/reference/frontend-api/tag/Client#operation/handshakeClient) -2. The `@clerk/backend` `authenticateRequest()` method +2. The `@clerk/backend` `authenticateRequest()` method. The isomorphic `@clerk/backend` SDK is used by all framework specific Clerk SDKs such as `@clerk/nextjs`. ### Handshake payload The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. +{/* TODO: Bryce to add an example of a handshake payload */} + To verify the handshake payload JWT, use the instance [public RSA key](https://clerk.com/docs/reference/frontend-api/tag/Well-Known#operation/GetJWKS). \ No newline at end of file diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index e85266484e..1f86833410 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -6,6 +6,12 @@ type: conceptual # How Clerk works +Clerk is a powerful authentication and user management system that allows you to add secure authentication to your application in minutes. This guide will discuss some of the main concepts and objects that power Clerk. + + + Did you know that Clerk has a blog? You can learn more in-depth about how Clerk works by reading our ["How We Roll"](https://clerk.com/blog/how-we-roll-roundup) blog series. + + ## Development and production instances Clerk provices both development and production environments for your app. Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. Development instances contain certain trade-offs meant to support ease of active development. @@ -88,11 +94,16 @@ Every Frontend API request returns a response payload that contains two top leve The `/v1/client/sessions/:id/tokens` endpoint refreshes the Clerk session tokens and is an exception to this format. - The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users, and organization data for the current device (see [Main Objects](#main-objects) section). This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the [React hooks](/docs/references/react/use-user), and [Clerk components](/docs/components/overview). It is a best-effort way for the backend to update the frontend state on every Frontend API request. +### Clerk Frontend API for non-standard web browsers + +Clerk's [Frontend API](https://clerk.com/docs/reference/frontend-api) offers a seamless authentication solution for non-standard web browser environments such as React Native applications, Chrome Extensions, and hybrid apps in platforms like Capacitor.js or Electron. + +These platforms treat cookies differently than web browsers. As a result, ClerkJS should use the HTTP Authorization header instead of the `__client` cookie for secure communication with the Clerk Frontend API. To achieve session persistence, the `__client` JWT should be stored in a secure storage provided by each platform and then it should be injected into every Clerk Frontend API request. + It's not recommended to use Client piggybacking because of the following issues: 1. It’s a very large chunk of a tree-like state and doesn’t change often. @@ -100,12 +111,6 @@ It's not recommended to use Client piggybacking because of the following issues: 1. It’s best effort. 1. It’s not a two-way communication channel. -### Clerk Frontend API for non-standard web browsers - -Clerk offers a seamless authentication solution for non-standard web browser environments such as React Native applications, Chrome Extensions, and hybrid apps in platforms like Capacitor.js or Electron. - -These platforms treat cookies differently than web browsers. As a result, ClerkJS should use the HTTP Authorization header instead of the `__client` cookie for secure communication with the Clerk Frontend API. To achieve session persistence, the `__client` JWT should be stored in a secure storage provided by each platform and then it should be injected into every Clerk Frontend API request. - ## Clerk Backend API (BAPI) Clerk's [Backend API](https://clerk.com/docs/reference/backend-api) is a restful CRUD API for the server side. It allows a sudo-level management of all Clerk objects. \ No newline at end of file From 996336870be80f8cfbef93f1aa431c778f762ac1 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:43:54 -0500 Subject: [PATCH 39/43] numbered points should be bullet points; update heading for clarity --- docs/concepts/client-handshake.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 225b093829..4fc28bc290 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -36,14 +36,14 @@ The handshake mechanism operates by way of a redirect from the host application A handshake is only triggered if a request is determined to be a document request (detected by the presence of the `Sec-Fetch-Dest: document` header, or `Accept: text/html`). Otherwise, the request is treated as `signed-out`. -1. Development instance and a dev browser is detected in URL +- Development instance and a dev browser is detected in URL [(URL-based session sync)](https://clerk.com/docs/upgrade-guides/url-based-session-syncing#url-based-session-syncing) -2. Production instance and request is being made to a satellite application -3. The current browser has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) -4. The current browser has an active client (`__client_uat` > 0) but no session token -5. The `client_uat` cookie indicating the latest timestamp a client was updated, is more recent than current session token issued at timestamp (`__client_uat` > `sessionToken.iat`) -6. The `__session` token cookie exists but is expired -7. The `__session` token cookie exists but is not active yet +- Production instance and request is being made to a satellite application +- The current browser has a session token (`__session`), but no active client is detected (`__client_uat` = 0 or missing) +- The current browser has an active client (`__client_uat` > 0) but no session token +- The `client_uat` cookie indicating the latest timestamp a client was updated, is more recent than current session token issued at timestamp (`__client_uat` > `sessionToken.iat`) +- The `__session` token cookie exists but is expired +- The `__session` token cookie exists but is not active yet ## Handshake architecture @@ -52,7 +52,7 @@ The handshake flow is composed of two main pieces: 1. The FAPI [`/client/handshake` endpoint](https://clerk.com/docs/reference/frontend-api/tag/Client#operation/handshakeClient) 2. The `@clerk/backend` `authenticateRequest()` method. The isomorphic `@clerk/backend` SDK is used by all framework specific Clerk SDKs such as `@clerk/nextjs`. -### Handshake payload +### Handshake payload for `/client/handshake` endpoint The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. From 2106eae6eac6ec25146579132bd240f6e8e645ed Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Mon, 5 Feb 2024 10:28:57 -0500 Subject: [PATCH 40/43] Update docs/concepts/client-handshake.mdx Co-authored-by: Sokratis Vidros --- docs/concepts/client-handshake.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 4fc28bc290..3b4aac9046 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -14,7 +14,7 @@ Clerk uses a mechanism called "the client handshake" to resolve a request’s au With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. -The resolution is fast and shouldn't be noticeable to the end user. +The resolution is blazing fast and usually happens at the Edge. ## Handshake flow From 086a917579082bfb057b019a98380bc89a92b3c0 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Mon, 5 Feb 2024 10:35:11 -0500 Subject: [PATCH 41/43] add section that explains __client_uat cookie --- docs/concepts/how-clerk-works.mdx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 1f86833410..3e7d15ec0b 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -71,6 +71,10 @@ The `__session` cookie is set on the host application that is secured by Clerk ( However, if a `__session` cookie is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. +#### The `__client_uat` cookie + +The `__client_uat` cookie is set on the host application that is secured by Clerk and hints Clerk SDKs about the timestamp of the latest authentication update of the current client. + ### The client handshake Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. @@ -85,8 +89,8 @@ Every Frontend API request returns a response payload that contains two top leve ```json { - "client": ..., - "response": ... + "client": ..., + "response": ... } ``` @@ -106,10 +110,10 @@ These platforms treat cookies differently than web browsers. As a result, ClerkJ It's not recommended to use Client piggybacking because of the following issues: -1. It’s a very large chunk of a tree-like state and doesn’t change often. -1. It’s hard to compute on the backend as it requires a lot of data from the database. The computation takes place on every request, adding a significant overhead. -1. It’s best effort. -1. It’s not a two-way communication channel. +1. It's a very large chunk of a tree-like state and doesn't change often. +1. It's hard to compute on the backend as it requires a lot of data from the database. The computation takes place on every request, adding a significant overhead. +1. It's best effort. +1. It's not a two-way communication channel. ## Clerk Backend API (BAPI) From b349829ed4cd5ab3221edbb6569755a2308c2f81 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Mon, 5 Feb 2024 10:36:01 -0500 Subject: [PATCH 42/43] add example of handshake payload --- docs/concepts/client-handshake.mdx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/concepts/client-handshake.mdx b/docs/concepts/client-handshake.mdx index 3b4aac9046..855ed0539a 100644 --- a/docs/concepts/client-handshake.mdx +++ b/docs/concepts/client-handshake.mdx @@ -1,6 +1,6 @@ --- title: Client handshake -description: The client handshake is a mechanism that is used to resolve a request’s authentication state from “unknown” to definitively signed in or signed out. +description: The client handshake is a mechanism that is used to resolve a request's authentication state from “unknown” to definitively signed in or signed out. type: conceptual --- @@ -10,7 +10,7 @@ type: conceptual This flow applies only to website browser traffic and not native applications. -Clerk uses a mechanism called "the client handshake" to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API (FAPI) while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. +Clerk uses a mechanism called "the client handshake" to resolve a request's authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. Clerk's session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that keeps the session JWT fresh by interacting with the Frontend API (FAPI) while the web application is active. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application's backend, the SDK doesn't know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. With the handshake, we can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. @@ -54,8 +54,17 @@ The handshake flow is composed of two main pieces: ### Handshake payload for `/client/handshake` endpoint -The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application’s domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. +The handshake payload is a signed JWT that contains an array of `set-cookie` header directives. This allows us to transfer cookies from the FAPI domain to the application's domain across environments without additional cookie setting logic embedded into our SDKs. In development, the payload is transported in the URL in a `__clerk_handshake` query parameter. In production, the payload is transported in a `__clerk_handshake` cookie. On returning from the handshake endpoint, the handshake payload is parsed and the cookie directives are set on the final response. -{/* TODO: Bryce to add an example of a handshake payload */} +Below is an example of a handshake payload: + +```json + "handshake": [ + "__client_uat=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT", + "__clerk_handshake=; Path=/; Domain=example.com; Expires=Thu, 01 Jan 1970 00:00:00 GMT", + "__client_uat=1706822359; Path=/; Domain=example.com; Max-Age=315360000; Secure; SameSite=Lax", + "__session=<...CLERK_SESSION_JWT...>; Path=/; Expires=Wed, 05 Feb 2025 09:08:53 GMT; Secure" + ] +``` To verify the handshake payload JWT, use the instance [public RSA key](https://clerk.com/docs/reference/frontend-api/tag/Well-Known#operation/GetJWKS). \ No newline at end of file From 4f9c0b1c90e7956e61eaf28f07d4667e795ec440 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:10:11 -0500 Subject: [PATCH 43/43] grammatical updates --- docs/concepts/how-clerk-works.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/concepts/how-clerk-works.mdx b/docs/concepts/how-clerk-works.mdx index 3e7d15ec0b..f8604f3e41 100644 --- a/docs/concepts/how-clerk-works.mdx +++ b/docs/concepts/how-clerk-works.mdx @@ -17,7 +17,7 @@ Clerk is a powerful authentication and user management system that allows you to Clerk provices both development and production environments for your app. Production instances are used for production, pre-production, or staging environments with fixed domains. Production instances offer the strongest security and performance guarantees. Development instances contain certain trade-offs meant to support ease of active development. -Never use a development instance in a production environment. Development instances don’t have strong security guarantees. +Never use a development instance in a production environment. Development instances don't have strong security guarantees. ## Main objects @@ -56,20 +56,20 @@ Clerk's Frontend API is responsible for maintaining the authentication state of ### Clerk cookies -Clerk’s Frontend API uses two cookies for session management in production instances: +Clerk's Frontend API uses two cookies for session management in production instances: * `__client` cookie: a long-lived session that is used to keep the the session JWT fresh by interacting with the Frontend API. * `__session` cookie: a short-lived session JWT to validate requests on your application or your API. #### The `__client` cookie -The `__client` cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It’s HTTP-only, first-party, and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. +The `__client` cookie is set on Clerk Frontend API (for example `https://clerk.`) for each instance. It's HTTP-only, first-party, and secure. It contains a long-lived client JWT that lasts 7 days by default. The duration is configurable in the Clerk Dashboard's [Sessions page](https://dashboard.clerk.com/last-active?path=sessions). The JWT identifies the current client (browser, native application, or chrome extension) and sets the current active sessions. #### The `__session` cookie -The `__session` cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It’s a JS cookie, it’s secure, and it contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user, and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR), ensuring a fresh session is always available. +The `__session` cookie is set on the host application that is secured by Clerk (for example `https://dashboard.`). It's a JS cookie, it's secure, and it contains a short-lived session JWT that lasts 60 seconds. This JWT contains the current session, user, and organization identifiers and must be sent to the application API to authenticate API requests. In SSR, the `__session` cookie travels automatically to the server. ClerkJS ensures that the `__session` cookie is automatically refreshed in Client Side Rendering (CSR) and Server Side Rendering (SSR), ensuring a fresh session is always available. -However, if a `__session` cookie is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. +However, if a `__session` cookie is expired on a request to an application's backend, the SDK doesn't know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers Clerk's client handshake. #### The `__client_uat` cookie @@ -77,7 +77,7 @@ The `__client_uat` cookie is set on the host application that is secured by Cler ### The client handshake -Clerk uses a client handshake mechanism to resolve a request’s authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. +Clerk uses a client handshake mechanism to resolve a request's authentication state from unknown (`handshake`) to `signed-in` or `signed-out`. With this handshake, Clerk can resolve authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially unknown state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. @@ -98,7 +98,7 @@ Every Frontend API request returns a response payload that contains two top leve The `/v1/client/sessions/:id/tokens` endpoint refreshes the Clerk session tokens and is an exception to this format. -The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The client object identifies the current device and contains all sessions, users, and organization data for the current device (see [Main Objects](#main-objects) section). +The `response` key contains the resource or resources of each endpoint. The `client` key contains the client piggybacking payload. The `client` object identifies the current device and contains all sessions, users, and organization data for the current device (see [Main Objects](#main-objects) section). This is effectively the necessary frontend state for ClerkJS and powers the JS SDKs, the [React hooks](/docs/references/react/use-user), and [Clerk components](/docs/components/overview). It is a best-effort way for the backend to update the frontend state on every Frontend API request.