AuthKit Next.js

repository·main·Indexed 41 days ago

https://github.com/workos/authkit-nextjs

Authentication and session management helpers for the Next.js App Router using WorkOS. Version 4.3.2 provides tools for configuring redirect URIs, managing session cookies via WORKOS_COOKIE_PASSWORD, and implementing authentication flows with handleAuth(), getSignInUrl(), and middleware/proxy support for Next.js 15 and 16+.

Tokens
19.6K
Snippets
68
Records
80
Agent score
99%

What's inside AuthKit Next.js

  1. Evaluate feature flags

    main

    There are two ways to evaluate feature flags:

    1. feature_flags claim: Use withAuth() to retrieve flags directly from the user's session. This is best for small flag sets. Flags update on the next login or session refresh.
    2. Runtime Client: Use getFeatureFlagsRuntimeClient() for large flag sets or when you need server-side evaluation that stays in sync independently of the user session. This client should be created once per server process.

    Note: When using the runtime client, call await featureFlags.waitUntilReady() to ensure the client is initialized.

    import { getFeatureFlagsRuntimeClient, withAuth } from '@workos-inc/authkit-nextjs';
    
    const featureFlags = getFeatureFlagsRuntimeClient();
    
    export default async function DashboardPage() {
      const { user, organizationId } = await withAuth({ ensureSignedIn: true });
    
      try {
        await featureFlags.waitUntilReady({ timeoutMs: 5000 });
      } catch (error) {
        console.error('Feature flags client failed to initialize:', error);
      }
    
      const enabled = featureFlags.isEnabled('advanced-analytics', {
        userId: user.id,
        organizationId,
      });
    
      return enabled ? <AdvancedAnalytics /> : <BasicAnalytics />;
    }
  2. How AuthKit and vinext work together

    main
    The AuthKit library works with vinext without a dedicated integration package because vinext shims the standard Next.js API surface (such as next/headers, next/server, and next/navigation). This allows the @workos-inc/authkit-nextjs library to interact with the environment as if it were running on a standard Next.js runtime.
  3. Optimize AuthKitProvider with Server-Side Auth Data

    main

    To prevent an extra server action call on mount in client components, you can pass initial authentication data from the server to the AuthKitProvider using the initialAuth prop.

    Note: You must remove the accessToken from the auth object before passing it to the client to ensure security.

    import { AuthKitProvider } from '@workos-inc/authkit-nextjs/components';
    import { withAuth } from '@workos-inc/authkit-nextjs';
    
    export default async function RootLayout({ children }: { children: React.ReactNode }) {
      // Fetch auth data on the server
      const auth = await withAuth();
    
      // Remove the accessToken from the auth object as it is not needed on the client side
      const { accessToken, ...initialAuth } = auth;
    
      return (
        <html lang="en">
          <body>
            <AuthKitProvider initialAuth={initialAuth}>{children}</AuthKitProvider>
          </body>
        </html>
      );
    }
  4. Initiate the AuthKit sign-in flow

    main

    To start the authentication process, create a route (e.g., /sign-in/route.ts) that uses getSignInUrl() and redirects the user to the resulting URL.

    Important: You must configure this route as the Initiate login URI (initiate_login_uri) in your WorkOS dashboard under Applications > [Your App] > Redirects. This is required for features like user impersonation to work correctly.

    // app/sign-in/route.ts
    import { getSignInUrl } from '@workos-inc/authkit-nextjs';
    import { redirect } from 'next/navigation';
    
    export const GET = async () => {
      const signInUrl = await getSignInUrl();
      return redirect(signInUrl);
    };
  5. Configure the AuthKit callback route

    main

    WorkOS requires a callback URL to redirect users back after authentication. You must expose an API route (Route Handler) in your Next.js app that uses handleAuth().

    This route's path must match your WORKOS_REDIRECT_URI environment variable and the redirect URI configured in your WorkOS dashboard (e.g., if your URI is /auth/callback, place the code in /app/auth/callback/route.ts).

    Key Options for handleAuth:

    • returnPathname: The path to redirect the user to after successful sign-in (defaults to /).
    • baseURL: The base URL for the redirect URI. Required if running in environments like Docker where the hostname differs from the request.
    • onSuccess: A callback function triggered after successful authentication to perform side-effects (e.g., saving tokens or updating a database).
    • onError: A callback function to handle authentication errors.
    import { handleAuth } from '@workos-inc/authkit-nextjs';
    
    // Basic usage
    export const GET = handleAuth();
    
    // With options
    export const GET = handleAuth({
      returnPathname: '/dashboard',
      baseURL: 'http://localhost:3000',
      onSuccess: async ({ user, oauthTokens, authenticationMethod, organizationId, state }) => {
        // Perform side-effects here
      },
    });
  6. Configure required environment variables

    main

    Before setting up AuthKit, ensure the following environment variables are defined in your .env.local file. These values are retrieved from your WorkOS dashboard.

    • WORKOS_CLIENT_ID: Your WorkOS Client ID.
    • WORKOS_API_KEY: Your WorkOS API Key.
    • WORKOS_COOKIE_PASSWORD: A secure private key (at least 32 characters) used to encrypt the session cookie.
    • NEXT_PUBLIC_WORKOS_REDIRECT_URI: The redirect URI configured in your WorkOS dashboard (e.g., http://localhost:3000/callback).

    To use the signOut method, you must also configure a default Sign-out URI in the WorkOS dashboard under the "Redirects" tab.

    WORKOS_CLIENT_ID="client_..."
    WORKOS_API_KEY="sk_test_..."
    WORKOS_COOKIE_PASSWORD="<your password>"
    NEXT_PUBLIC_WORKOS_REDIRECT_URI="http://localhost:3000/callback"
  7. Set up AuthKit Proxy/Middleware

    main

    The library uses Next.js middleware/proxy to manage sessions. The implementation depends on your Next.js version:

    • Next.js 16+: Create a proxy.ts file in your project root using authkitProxy().
    • Next.js ≤15: Create a middleware.ts file in your project root using authkitMiddleware().

    Warning on Matchers: Avoid using catch-all patterns that intercept static assets (like _next/static), as this can break styles. Use an exclusion pattern if necessary.

    Middleware Options:

    • redirectUri: Set a dynamic redirect URI (useful for Vercel preview deployments).
    • debug: Enables debug logs.
    • signUpPaths: Array of paths that should trigger the 'sign-up' screen hint.
    • eagerAuth: Enables synchronous access token availability.
    • refreshBufferSeconds: Seconds before expiry to proactively refresh the session (default 60).
    // Next.js 16+ (proxy.ts)
    import { authkitProxy } from '@workos-inc/authkit-nextjs';
    export default authkitProxy();
    export const config = { matcher: ['/', '/admin'] };
    
    // Next.js ≤15 (middleware.ts)
    import { authkitMiddleware } from '@workos-inc/authkit-nextjs';
    export default authkitMiddleware();
    export const config = { matcher: ['/', '/admin'] };
    
    // Recommended matcher to avoid breaking static assets
    export const config = {
      matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
    };
  8. Pass custom state through authentication

    main

    You can pass arbitrary data through the OAuth flow using the state parameter. Because state is an opaque string, you must serialize complex data using JSON.stringify() when generating URLs and JSON.parse() when handling the callback.

    Usage Pattern:

    1. Serialize data: getSignInUrl({ state: JSON.stringify(myData) })
    2. Retrieve in callback: onSuccess: async ({ state }) => { const data = JSON.parse(state); }
    // 1. Generate URL with serialized state
    const signInUrl = await getSignInUrl({
      state: JSON.stringify({
        teamId: 'team_123',
        feature: 'billing',
      }),
    });
    
    // 2. Handle in callback
    export const GET = handleAuth({
      onSuccess: async ({ user, state }) => {
        const customData = state ? JSON.parse(state) : null;
        if (customData?.teamId) {
          await addUserToTeam(user.id, customData.teamId);
        }
      },
    });
  9. Deploy AuthKit + vinext to Cloudflare Workers

    main

    To deploy your vinext application to Cloudflare Workers:

    1. Set Secrets: Use the Wrangler CLI to upload your WorkOS credentials as Worker secrets. Ensure NEXT_PUBLIC_WORKOS_REDIRECT_URI matches your deployed Workers URL (e.g., https://<your-app>.<subdomain>.workers.dev/callback).
    2. Update WorkOS Dashboard: Add the new production callback URL to your WorkOS redirect URIs.
    3. Deploy: Run the deploy command to trigger the vinext deploy process, which handles Cloudflare-specific build configurations.

    To test the Workers runtime locally (matching production behavior), use a .dev.vars file and run wrangler dev instead of the standard dev server.

    # Set secrets
    wrangler secret put WORKOS_CLIENT_ID
    wrangler secret put WORKOS_API_KEY
    wrangler secret put WORKOS_COOKIE_PASSWORD
    wrangler secret put NEXT_PUBLIC_WORKOS_REDIRECT_URI
    
    # Deploy
    pnpm run deploy
    
    # Local Workers testing
    cp .dev.vars.example .dev.vars
    wrangler dev
  10. Configure WorkOS Redirect URIs and Environment Variables

    main

    To use AuthKit with Next.js, you must configure your WorkOS dashboard and local environment variables.

    1. WorkOS Dashboard Configuration:

      • Set your app homepage URL to http://localhost:3000.
      • Create a sign-in callback redirect for http://localhost:3000/callback in the Redirects tab.
    2. Environment Variables:

      • Copy your Client ID and Secret Key from the API keys tab.
      • Create a WORKOS_COOKIE_PASSWORD which is a private key used to encrypt the session cookie. This must be at least 32 characters long.
      • Create a .env.local file in your project root with the following keys.
    WORKOS_CLIENT_ID=<YOUR_CLIENT_ID>
    WORKOS_API_KEY=<YOUR_API_SECRET_KEY>
    WORKOS_COOKIE_PASSWORD=<YOUR_COOKIE_PASSWORD>
    
    NEXT_PUBLIC_WORKOS_REDIRECT_URI=http://localhost:3000/callback