Authorization

Authorization

Now that you have set up and configured authentication with Convex Auth, learn how to use the authentication state in your frontend and backend.

Sign in

See each authentication method's Configuration page for how to build a sign-in UI.

Sign out

You can sign the user out via the signOut function:

src/SignOut.tsx
import { useAuthActions } from "@convex-dev/auth/react";
 
export function SignOut() {
  const { signOut } = useAuthActions();
  return <button onClick={() => void signOut()}>Sign out</button>;
}

Determine what UI to show based on signed-in state

You can control which content signed-in and signed-out users can see with the components from convex/react. You can combine them with your custom sign-in and sign-out components:

src/App.tsx
import { Authenticated, Unauthenticated, AuthLoading } from "convex/react";
import { SignIn } from "./SignIn";
import { SignOut } from "./SignOut";
 
export function App() {
  return (
    <>
      <AuthLoading>{/* consider showing a loading indicator */}</AuthLoading>
      <Unauthenticated>
        <SignIn />
      </Unauthenticated>
      <Authenticated>
        <SignOut />
        <Content />
      </Authenticated>
    </>
  );
}
 
function Content() {
  /* render signed-in content */
}

Authenticate HTTP actions

Sometimes your React frontend might need to call your Convex backend via HTTP, usually to stream data, such as when uploading files or when loading a slowly generated AI response.

To authenticate HTTP actions calls you will need to access the JWT token the client uses for authenticating with the backend, which you get from the useAuthToken hook:

import { useAuthToken } from "@convex-dev/auth/react";
 
function SomeComponent() {
  const token = useAuthToken();
  const onClick = async () => {
    // You might need to set up `VITE_CONVEX_SITE_URL`
    const response = await fetch(
      `${process.env.VITE_CONVEX_SITE_URL!}/someEndpoint`,
      { headers: { Authorization: `Bearer ${token}` } },
    );
    // ...
  };
  // ...
}

Use authentication state in backend functions

Within a Convex function (opens in a new tab), you can access information about the currently logged-in user and session via helper functions exported from @convex-dev/auth/server file.

The getAuthUserId and getAuthSessionId methods use the Convex-built-in ctx.auth.getUserIdentity() under the hood and provide a typed API.

Data model

Convex Auth defines users and authSessions tables for you.

When a user first signs up, a document is created in the users table.

When a user signs in (including after initial sign-up), a document is created in the authSessions table. The session document exists until the session expires or the user signs out. See session document lifecycle.

One user can have many active sessions simultaneously. For web apps the same session is shared by all browser tabs by default, but this can be configured.

Get currently signed-in user ID

To get the currently signed-in user's ID, call getAuthUserId and pass it a query, mutation or action ctx:

convex/myFunctions.tsx
import { getAuthUserId } from "@convex-dev/auth/server";
import { query } from "./_generated/server";
 
export const currentUser = query({
  args: {},
  handler: async (ctx) => {
    const userId = await getAuthUserId(ctx);
    if (userId === null) {
      return null;
    }
    return await ctx.db.get(userId);
  },
});

The function returns Id<"users"> (or null when the client isn't authenticated).

Get current session ID

To get the current session ID, call getAuthSessionId and pass it a query, mutation or action ctx:

convex/myFunctions.tsx
import { getAuthSessionId } from "@convex-dev/auth/server";
import { query } from "./_generated/server";
 
export const currentSession = query({
  args: {},
  handler: async (ctx) => {
    const sessionId = await getAuthSessionId(ctx);
    if (sessionId === null) {
      return null;
    }
    return await ctx.db.get(sessionId);
  },
});

The function returns Id<"authSessions"> (or null when the client isn't authenticated).

Loading users and sessions

You can retrieve the user or session document via ctx.db.get() in queries and mutations.

See Customizing Schema for guidance on attaching additional information to users and sessions.

Detecting anonymous users

If you enabled anonymous sign-in, the user ID returned by getAuthUserId might belong to an anonymous user. You might want to restrict what anonymous users can do compared to authenticated users. To do this, load the current user and check the isAnonymous field:

convex/myFunctions.tsx
import { mutation } from "./_generated/server";
import { auth } from "./auth";
 
export const doSomethingAfterProperSignIn = mutation({
  args: {
    /* ... */
  },
  handler: async (ctx, args) => {
    const userId = await getAuthUserId(ctx);
    if (userId === null) {
      throw new Error("Client is not authenticated!");
    }
    const user = await ctx.db.get(userId);
    if (user.isAnonymous) {
      throw new Error("User must sign in with an authentication method!");
    }
    // ...
  },
});

Server-side authentication in Next.js

You can set up your Next.js App Router app to have access to the authentication state on the server.

See the dedicated Next.js page.