new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Supabase · Auth · all subjects

authentication/sessions

28 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Session definition and representation

A session is created when a user signs in. By default, it lasts indefinitely and a user can have an unlimited number of active sessions on as many devices. A session is represented by a Supabase Auth access token in the form of a JWT, and a refresh token which is a unique string.

Access token and refresh token lifetimes

Access tokens are designed to be short lived, usually between 5 minutes and 1 hour. Refresh tokens never expire but can only be used once. You can exchange a refresh token only once to get a new access and refresh token pair. This process is called refreshing the session.

Session termination conditions

A session terminates when: the user clicks sign out, the user changes their password or performs a security sensitive action, it times out due to inactivity, it reaches its maximum lifetime, or a user signs in on another device.

Session flows

There are two flows for initiating a session and receiving tokens: Implicit flow and PKCE flow.

Session lifetime limiting (Pro Plan feature)

Session lifetime limiting is only available on Pro Plans and up. Supabase Auth can be configured to limit the lifetime of a user's session via three methods: time-boxed sessions which terminate after a fixed amount of time, inactivity timeout which terminates sessions that haven't been refreshed within the timeout duration, and enforce single-session per user which only keeps the most recently active session.

Time-box user sessions setting

To make sure that users are required to re-authenticate periodically, you can set a positive value for the Time-box user sessions option in the Auth settings for your project. When this is enabled, sessions terminate after the configured fixed amount of time.

Inactivity timeout setting

To make sure that sessions expire after a period of inactivity, you can set a positive duration for the Inactivity timeout option in the Auth settings. Sessions are terminated if they haven't been refreshed within the timeout duration.

Single session per user setting

You can enforce only one active session per user per device or browser via the Single session per user option in the Auth settings. When this is enabled, the session from the most recent sign in will remain active, while the rest are terminated.

Session limit setting enforcement timing

Sessions are not proactively destroyed when you change session limit settings, but rather the check is enforced whenever a session is refreshed next. The actual duration of a session is the configured timeout plus the JWT expiration time. For single session per user, the effect will only be noticed at intervals of the JWT expiration time.

Session cleanup from database

Sessions are progressively deleted from the database 24 hours after they expire. This prevents high load on the project and allows some freedom to undo changes without adversely affecting all users.

Refresh token reuse detection

The general rule is that a refresh token can only be used once. However, there are two exceptions to prevent unexpected session termination: a refresh token can be used more than once within a defined reuse interval (default 10 seconds, not recommended to change), and if the parent of the currently active refresh token for the user's session is being used, the active token will be returned.

Refresh token reuse detection security purpose

Refresh token reuse detection guards against potential security issues where a refresh token could have been stolen and used by an attacker, such as by exposing it in leaked logs or via vulnerable third-party servers. It does not guard against the case where a user's entire session is stolen from their device.

Session termination on refresh token reuse violation

When a refresh token reuse attempt does not fall within the defined reuse exceptions, the whole session is regarded as terminated and all refresh tokens belonging to it are marked as revoked. You can disable this behavior in the Advanced Settings of the Auth settings page, though it is generally not recommended.

Validating access token after sign out

When a user signs out, the sessions affected by the logout are removed from the database entirely. To ensure an access token cannot be used after a user signs out, you should check that the session_id claim in the JWT corresponds to a row in the auth.sessions table. If such a row does not exist, it means that the user has logged out. Most applications rarely need such strong guarantees and should consider adjusting JWT expiry time instead.

signOut removes browser session and localStorage

The signOut() method removes the user from the browser session and any objects from localStorage (or local storage in C#).

Sign out using Flutter

Call supabase.auth.signOut() to remove the user from the browser session and clear any objects from localStorage. Example: ```dart Future<void> signOut() async { await supabase.auth.signOut(); } ```

Sign out using JavaScript

To sign out a user in JavaScript, call supabase.auth.signOut() to remove them from the browser session and any objects from localStorage.

Sign out using Flutter

To sign out a user in Flutter, call supabase.auth.signOut() to remove them from the browser session and any objects from localStorage.

Sign out using Kotlin

To sign out a user in Kotlin, call supabase.auth.signOut() to remove them from the browser session and any objects from localStorage.

Flutter example: sign out user

Call supabase.auth.signOut() to remove the user from the browser session and any objects from localStorage: Future<void> signOut() async { await supabase.auth.signOut(); }

JavaScript example: sign out user

Call supabase.auth.signOut() to remove the user from the browser session and any objects from localStorage: async function signOut() { const { error } = await supabase.auth.signOut() }

Swift example: sign out user

Call supabase.auth.signOut() to remove the user from the browser session: func signOut() async throws { try await supabase.auth.signOut() }

Kotlin example: sign out user

Call supabase.auth.signOut() to remove the user from the browser session and any objects from localStorage: suspend fun signOut() { supabase.auth.signOut() }

C# example: sign out user

Call supabase.Auth.SignOut() to remove the user from the browser session and any objects from local storage: await supabase.Auth.SignOut();

Sign out implementation across SDKs

Sign out is implemented via signOut() method in JavaScript and Flutter (removes session and localStorage), signOut() in Kotlin, and SignOut() in C#. All methods remove the user from the browser session and local storage.

Token refresh rate limits

The `/auth/v1/token` endpoint for token refresh requests is rate limited by IP Address. The limit is auth.rate_limits.token_refresh.requests_per_hour requests per hour with bursts up to auth.rate_limits.token_refresh.requests_burst requests. This limit is not customizable.

RLS with session variable for direct Postgres connection

When connecting directly to Supabase Postgres instead of via REST API, use a custom session variable to determine the current user. Set the variable using 'set app.current_user_id = <current-user-id>' at the beginning of each session, then access it in RLS policies using current_setting('app.current_user_id')::datatype. All subsequent queries will respect this user context.

auth.uid() in RLS policies with REST API

When executing queries through Supabase's auto-generated REST API, the current user is determined using the built-in auth.uid() function. This function automatically references current_setting('request.jwt.claim.sub') which corresponds to the JWT's sub (subject) claim.

Give your agent this brain