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/methods

414 notes in this subject, read out of this brain and free to use. This is page 7 of 7.

Kotlin sign-out example

To sign out in Kotlin, call supabase.auth.signOut(): ```kotlin suspend fun signOut() { supabase.auth.signOut() } ```

Sign in with Zoom using JavaScript client

To sign in with Zoom in JavaScript, call supabase.auth.signInWithOAuth() with provider set to 'zoom'. Example: const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'zoom' })

Sign in with Zoom using Flutter client

To sign in with Zoom in Flutter, call supabase.auth.signInWithOAuth() with OAuthProvider.zoom. Optionally set redirectTo for deeplink on mobile and authScreenLaunchMode to control whether the auth screen launches in a new webview on mobile or platformDefault on web.

Sign in with Zoom using Kotlin client

To sign in with Zoom in Kotlin, call supabase.auth.signInWith(Zoom) as a suspend function.

Sign in with Zoom using C# client

To sign in with Zoom in C#, call supabase.Auth.SignIn(Provider.Zoom) and retrieve the sign-in URL from the returned state object's Uri property.

WorkOS signInWithOAuth code example

Example of signing in with WorkOS: ```javascript import { createClient } from '@supabase/supabase-js'; const supabase = createClient('https://your-project-id.supabase.co', 'sb_publishable_...'); async function signInWithWorkOS() { const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'workos', options: { redirectTo: 'http://example.com/auth/v1/callback', queryParams: { connection: '<connection_id>', }, }, }) if (data.url) { redirect(data.url) } } ```

signInWithOAuth with WorkOS provider

To sign in a user with WorkOS, call supabase.auth.signInWithOAuth with provider set to 'workos'. The options object should include redirectTo (the callback URL configured in Supabase Dashboard Auth settings) and queryParams with connection set to the connection_id found in the WorkOS dashboard under Organizations tab (select your organization and click View connection). The returned data.url should be used to redirect the user.

WorkOS OAuth callback handling with code exchange

At your specified OAuth callback URL, exchange the authorization code for a session using supabase.auth.exchangeCodeForSession(code). The code parameter is extracted from the URL search parameters. After successful exchange, redirect the user to the application using the origin and optional next parameter (defaulting to '/' if not provided or if not a relative URL).

WorkOS callback route exchange code for session

Example callback route that exchanges authorization code for session: ```typescript import { NextResponse } from 'next/server' import { createClient } from '@/utils/supabase/server' export async function GET(request: Request) { const { searchParams, origin } = new URL(request.url) const code = searchParams.get('code') let next = searchParams.get('next') ?? '/' if (!next.startsWith('/')) { next = '/' } if (code) { const supabase = await createClient() const { error } = await supabase.auth.exchangeCodeForSession(code) if (!error) { const forwardedHost = request.headers.get('x-forwarded-host') const isLocalEnv = process.env.NODE_ENV === 'development' if (isLocalEnv) { return NextResponse.redirect(`${origin}${next}`) } else if (forwardedHost) { return NextResponse.redirect(`https://${forwardedHost}${next}`) } else { return NextResponse.redirect(`${origin}${next}`) } } } return NextResponse.redirect(`${origin}/auth/auth-code-error`) } ```

Clerk setup via Clerk's Connect with Supabase page

To configure Clerk for Supabase compatibility, visit Clerk's Connect with Supabase page at https://dashboard.clerk.com/setup/supabase. After configuring, add a new Third-Party Auth integration with Clerk in the Supabase dashboard.

Clerk local development configuration in supabase/config.toml

For local development or self-hosting with the Supabase CLI, add the following configuration to the supabase/config.toml file under [auth.third_party.clerk]: enabled = true and domain = "example.clerk.accounts.dev". You must still configure your Clerk instance for Supabase compatibility.

Manual Clerk configuration: add role claim to session tokens

If unable to use Clerk's automated setup, manually configure Clerk by adding the role claim to Clerk session tokens through customization. End-users who are authenticated should have the 'authenticated' value for this claim. If your Postgres setup uses different roles for different authenticated users, adjust the value to match the correct role name.

Clerk as third-party auth provider with Supabase

Clerk can be used as a third-party authentication provider alongside Supabase Auth, or as a standalone authentication service with your Supabase project.

Clerk TypeScript client setup with Supabase

In TypeScript, set up the Supabase client to use Clerk session tokens as the access token for authentication with Supabase.

Clerk Flutter client setup with Supabase

In Flutter, import clerk_flutter and supabase_flutter packages. Initialize Supabase with the SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY. Pass an accessToken function that retrieves the Clerk session token via ClerkAuth.of(context).sessionToken() and returns its jwt property.

Clerk Swift client setup with Supabase

In Swift (iOS), import Clerk and Supabase packages. Initialize a SupabaseClient with the supabaseURL and supabaseKey. In the auth options, set the accessToken to an async function that retrieves the token via try await Clerk.shared.session?.getToken()?.jwt.

Clerk integration with Supabase deprecated as of April 1, 2025

The previously available Clerk Integration with Supabase is deprecated and no longer recommended as of April 1, 2025. Projects using the deprecated integration are excluded from Third-Party Monthly Active User (TP-MAU) charges until at least January 1, 2026. The deprecated integration used low-level primitives like configurable JWT secrets and Clerk JWT templates, but this approach is no longer supported.

Why Clerk-Supabase integration was deprecated

The Clerk integration was deprecated because: (1) sharing a project's JWT secret with a third-party is a problematic security practice, (2) rotating the JWT secret results in significant downtime, and (3) using JWT templates adds latency compared to using Clerk session tokens directly.

No migration needed for existing third-party auth users

If you already have production apps using one of the supported third-party authentication providers, you can use Supabase features without needing to migrate your users to Supabase Auth or use workarounds like translating JWTs into Supabase Auth format.

Third-party auth key rotation update delay

JWT signing keys from the third-party provider are stored in your project configuration and checked for changes periodically. When rotating keys (if supported), allow up to 30 minutes for the change to be picked up by Supabase.

Supabase Auth cannot be disabled with third-party auth

It is not possible to disable Supabase Auth when using third-party authentication providers.

Third-party auth providers with first-class support

Supabase has first-class support for the following third-party authentication providers: Clerk, Firebase Auth, Auth0, AWS Cognito (with or without AWS Amplify), and WorkOS.

Third-party auth integration with Supabase products

Third-party authentication providers can be used alongside Supabase Auth or on their own to access Supabase Data API (REST and GraphQL), Storage, Realtime, and Functions.

Create Supabase client with Firebase Auth accessToken (Kotlin Multiplatform)

Use createSupabaseClient with an accessToken property that returns Firebase.auth.currentUser?.getIdToken(false) using the community Firebase Kotlin SDK for multiplatform support.

Create Supabase client with Firebase Auth accessToken (TypeScript)

Import createClient from '@supabase/supabase-js' and pass an accessToken async function that returns the Firebase Auth JWT of the current user or null: const supabase = createClient('https://<supabase-project>.supabase.co', 'SUPABASE_PUBLISHABLE_KEY', { accessToken: async () => { return (await firebase.auth().currentUser?.getIdToken(/* forceRefresh */ false)) ?? null } })

Create Supabase client with Firebase Auth accessToken (Flutter/Dart)

Use Supabase.initialize with an accessToken async function that returns the Firebase Auth JWT: await Supabase.initialize( url: supabaseUrl, publishableKey: publishableKey, debug: false, accessToken: () async { final token = await FirebaseAuth.instance.currentUser?.getIdToken(); return token; }, );

Create Supabase client with Firebase Auth accessToken (Swift iOS)

Import Supabase and FirebaseAuth, then create a SupabaseClient with an accessToken function in SupabaseClientOptions.AuthOptions that returns the ID token from Auth.auth().currentUser?.getIDToken() or throws MissingFirebaseTokenError.

Force refresh Firebase ID token after sign-up for role claim

After sign-up, if using an onCreate Cloud Function to add the role: 'authenticated' custom claim, the function does not run synchronously. You must call getIdToken(/* forceRefresh */ true) immediately after sign-up to fetch an ID token with the applied role.

Blocking Firebase Authentication function to assign role claim

Use a blocking Firebase Authentication function to automatically assign the role: 'authenticated' custom claim on user creation and sign-in. This approach is easier but only available if your Firebase project uses Firebase Authentication with Identity Platform.

Blocking function example Node.js: set role on creation and sign-in

Use beforeUserCreated and beforeUserSignedIn blocking functions to set customClaims with role: 'authenticated'. Example: import { beforeUserCreated, beforeUserSignedIn } from 'firebase-functions/v2/identity'; export const beforecreated = beforeUserCreated((event) => { return { customClaims: { role: 'authenticated' } } }); export const beforesignedin = beforeUserSignedIn((event) => { return { customClaims: { role: 'authenticated' } } });

Blocking function example Python: set role on creation and sign-in

Use identity_fn.before_user_created() and identity_fn.before_user_signed_in() decorators to set custom_claims with role: 'authenticated'. Example: @identity_fn.before_user_created() returns identity_fn.BeforeCreateResponse(custom_claims={'role': 'authenticated'}); @identity_fn.before_user_signed_in() returns identity_fn.BeforeSignInResponse(custom_claims={'role': 'authenticated'});

onCreate Cloud Function to assign role claim to new users

Manually assign the role: 'authenticated' custom claim to new Firebase users using an onCreate Cloud Function. This approach does not run synchronously, so the very first ID token will not contain the role claim. Example: exports.processSignUp = functions.auth.user().onCreate(async (user) => { try { await getAuth().setCustomUserClaims(user.uid, { role: 'authenticated' }) } catch (error) { console.log(error) } })

Assign role custom claim to existing Firebase users via admin SDK

Run a script using the Firebase admin SDK to assign role: 'authenticated' custom claim to all existing users. Use getAuth().listUsers() to fetch users in batches and getAuth().setCustomUserClaims() to set the claim. Process with Promise.all() for batch operations.

Script to batch assign role custom claim to all Firebase users

Use getAuth().listUsers(1000, nextPageToken) to list users in batches of 1000, then use Promise.all() to assign role: 'authenticated' via getAuth().setCustomUserClaims(userRecord.id, { role: 'authenticated' }) for each user. Loop until pageToken is undefined.

Deploy Firebase functions after configuration

After creating or modifying Firebase Authentication functions, deploy them with: firebase deploy --only functions

Existing Firebase users won't have role claim until manually assigned

Firebase Authentication functions (both blocking and onCreate) are only called on new sign-ups and sign-ins. Existing users will not have the role: 'authenticated' claim in their ID tokens unless you manually assign it using the admin SDK.

Email and phone identity sign-in options

A user with an email or phone identity will be able to sign in with either a password or passwordless method, such as using a one-time password (OTP) or magic link. By default, a user with an unverified email or phone number will not be able to sign in.

Sign-in methods

A user can sign in with one of the following methods: password-based method (with email or phone), passwordless method (with email or phone), OAuth, or SAML SSO.

Redirect URL requirements for invitations

The redirectTo URL must be in your project's allowed redirect URLs configuration. If it isn't, the redirectTo value is ignored and the invite link redirects to your Site URL instead (no error is raised).

Invitation link expiration

Invitation links expire after the duration configured in Email OTP Expiration, which defaults to 1 hour. This is the same value used for email OTPs, magic links, and other email confirmation links. If an invitation expires before it's accepted, send the user a new invite.

Invite user via Auth Admin API

Call inviteUserByEmail() from the SDK's Auth Admin API in a server-side environment using your project's secret key. You can optionally attach custom user_metadata and a redirect URL for the invite link. Example: const { data, error } = await supabase.auth.admin.inviteUserByEmail('someone@example.com', { data: { name: 'Jane' }, redirectTo: 'https://example.com/welcome' })

Invite user via Dashboard

To invite a user via Dashboard: go to Authentication > Users, click Add user and select Send invitation, enter the user's email address and click Invite user.

User invitation process and requirements

Inviting a user is an admin action that must be performed from a trusted server environment using the secret key, or from the Dashboard. When you invite an email that doesn't yet belong to a user, a new unconfirmed user is created. Inviting an email that already belongs to a confirmed user returns an error.

Sign up with user metadata - JavaScript example

const { data, error } = await supabase.auth.signUp({ email: 'valid.email@supabase.io', password: 'exa••••••rd', options: { data: { first_name: 'John', age: 27, }, }, })

Retrieve user metadata - JavaScript example

const { data: { user }, } = await supabase.auth.getUser() let metadata = user?.user_metadata

Comparison of getClaims, getUser, and getSession for authorization

Use getClaims to verify identity and protect pages and data. Use getUser when you need an up-to-date user record from the Auth server. Use getSession when you need the access or refresh token directly, but don't rely on the user object it returns for authorization decisions.

When to trust user object from getSession

The embedded user object from getSession shouldn't be trusted on its own when storage is shared with the client (such as with cookies or request headers). To verify identity, validate the access token with getClaims, or call getUser for a fresh, server-confirmed user record.

getSession function purpose and behavior

getSession returns the raw session including the access token, refresh token, and expiry. The session is loaded directly from local storage and isn't re-validated against the Auth server. Use getSession when you need the access or refresh token to forward to another service. Do not rely on the user object it returns for authorization decisions.

getClaims function purpose and behavior

getClaims reads the access token from storage and verifies it locally. It verifies tokens locally via the WebCrypto API and a cached JWKS endpoint when the project uses asymmetric signing keys (the default for new projects), or by calling getUser solely to validate when symmetric keys are in use. The returned claims always come from decoding the JWT, not from a user lookup. getClaims should be used to protect pages and user data.

getUser function purpose and behavior

getUser makes a network call to the project's Auth instance to get the user record, which includes the most up-to-date information about the user. This comes at the cost of a network call. Use getUser when you need an up-to-date user record from the Auth server.

Asymmetric vs symmetric signing key validation in getClaims

When getClaims verifies tokens with asymmetric signing keys (the default for new projects), it uses the WebCrypto API and a cached JWKS endpoint. When symmetric keys are in use, it validates by calling getUser solely.

Verification request rate limits

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

Email send rate limits and customization

Endpoints `/auth/v1/signup`, `/auth/v1/recover`, and `/auth/v1/user` that trigger email sends are rate limited by the sum of combined requests project-wide. The built-in email provider has a limit of emails per hour (config value: auth.rate_limits.email.inbuilt_smtp_per_hour). The rate limit is customizable only with a custom SMTP setup. On `/auth/v1/user`, the rate limit applies only when the endpoint is called to update the user's email address.

Supabase Auth provides Phone Auth providers

Supabase Auth supports Phone Auth using third-party providers for authentication via phone numbers.

Give your agent this brain