npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@workos-inc/authkit-nextjs

v0.16.1

Published

Authentication and session helpers for using WorkOS & AuthKit with Next.js

Downloads

16,890

Readme

AuthKit Next.js Library

The AuthKit library for Next.js provides convenient helpers for authentication and session management using WorkOS & AuthKit with Next.js.

Note: This library is intended for use with the Next.js App Router.

Installation

Install the package with:

npm i @workos-inc/authkit-nextjs

or

yarn add @workos-inc/authkit-nextjs

Video tutorial

Pre-flight

Make sure the following values are present in your .env.local environment variables file. The client ID and API key can be found in the WorkOS dashboard, and the redirect URI can also be configured there.

WORKOS_CLIENT_ID="client_..." # retrieved from the WorkOS dashboard
WORKOS_API_KEY="sk_test_..." # retrieved from the WorkOS dashboard
WORKOS_COOKIE_PASSWORD="<your password>" # generate a secure password here
NEXT_PUBLIC_WORKOS_REDIRECT_URI="http://localhost:3000/callback" # configured in the WorkOS dashboard

WORKOS_COOKIE_PASSWORD is the private key used to encrypt the session cookie. It has to be at least 32 characters long. You can use the 1Password generator or the openssl library to generate a strong password via the command line:

openssl rand -base64 24

To use the signOut method, you'll need to set your app's homepage in your WorkOS dashboard settings under "Redirects".

Optional configuration

Certain environment variables are optional and can be used to debug or configure cookie settings.

WORKOS_COOKIE_MAX_AGE='600' # maximum age of the cookie in seconds. Defaults to 400 days, the maximum allowed in Chrome
WORKOS_COOKIE_DOMAIN='example.com'
WORKOS_COOKIE_NAME='authkit-cookie'
WORKOS_API_HOSTNAME='api.workos.com' # base WorkOS API URL
WORKOS_API_HTTPS=true # whether to use HTTPS in API calls
WORKOS_API_PORT=3000 # port to use for API calls

WORKOS_COOKIE_DOMAIN can be used to share WorkOS sessions between apps/domains. Note: The WORKOS_COOKIE_PASSWORD would need to be the same across apps/domains. Not needed for most use cases.

Setup

Callback route

WorkOS requires that you have a callback URL to redirect users back to after they've authenticated. In your Next.js app, expose an API route and add the following.

import { handleAuth } from '@workos-inc/authkit-nextjs';

export const GET = handleAuth();

Make sure this route matches the WORKOS_REDIRECT_URI variable and the configured redirect URI in your WorkOS dashboard. For instance if your redirect URI is http://localhost:3000/auth/callback then you'd put the above code in /app/auth/callback/route.ts.

You can also control the pathname the user will be sent to after signing-in by passing a returnPathname option to handleAuth like so:

export const GET = handleAuth({ returnPathname: '/dashboard' });

handleAuth can be used with several options.

| Option | Default | Description | | ---------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | returnPathname | / | The pathname to redirect the user to after signing in | | baseURL | undefined | The base URL to use for the redirect URI instead of the one in the request. Useful if the app is being run in a container like docker where the hostname can be different from the one in the request |

Middleware

This library relies on Next.js middleware to provide session management for routes. Put the following in your middleware.ts file in the root of your project:

import { authkitMiddleware } from '@workos-inc/authkit-nextjs';

export default authkitMiddleware();

// Match against pages that require auth
// Leave this out if you want auth on every resource (including images, css etc.)
export const config = { matcher: ['/', '/admin'] };

The middleware can be configured with several options.

| Option | Default | Description | | ---------------- | ----------- | ------------------------------------------------------------------------------------------------------ | | redirectUri | undefined | Used in cases where you need your redirect URI to be set dynamically (e.g. Vercel preview deployments) | | middlewareAuth | undefined | Used to configure middleware auth options. See middleware auth for more details. | | debug | false | Enables debug logs. | | signUpPaths | [] | Used to specify paths that should use the 'sign-up' screen hint when redirecting to AuthKit. |

Custom redirect URI

In cases where you need your redirect URI to be set dynamically (e.g. Vercel preview deployments), use the redirectUri option in authkitMiddleware:

import { authkitMiddleware } from '@workos-inc/authkit-nextjs';

export default authkitMiddleware({
  redirectUri: 'https://foo.example.com/callback',
});

// Match against pages that require auth
// Leave this out if you want auth on every resource (including images, css etc.)
export const config = { matcher: ['/', '/admin'] };

Custom redirect URIs will be used over a redirect URI configured in the environment variables.

Usage

Wrap your app in AuthKitProvider

Use AuthKitProvider to wrap your app layout, which adds some protections for auth edge cases.

import { AuthKitProvider } from '@workos-inc/authkit-nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <AuthKitProvider>{children}</AuthKitProvider>
      </body>
    </html>
  );
}

Get the current user

For pages where you want to display a signed-in and signed-out view, use withAuth to retrieve the user profile from WorkOS.

import Link from 'next/link';
import { getSignInUrl, getSignUpUrl, withAuth, signOut } from '@workos-inc/authkit-nextjs';

export default async function HomePage() {
  // Retrieves the user from the session or returns `null` if no user is signed in
  const { user } = await withAuth();

  if (!user) {
    // Get the URL to redirect the user to AuthKit to sign in
    const signInUrl = await getSignInUrl();

    // Get the URL to redirect the user to AuthKit to sign up
    const signUpUrl = await getSignUpUrl();

    return (
      <>
        <Link href={signInUrl}>Log in</Link>
        <Link href={signUpUrl}>Sign Up</Link>
      </>
    );
  }

  return (
    <form
      action={async () => {
        'use server';
        await signOut();
      }}
    >
      <p>Welcome back {user?.firstName && `, ${user?.firstName}`}</p>
      <button type="submit">Sign out</button>
    </form>
  );
}

Requiring auth

For pages where a signed-in user is mandatory, you can use the ensureSignedIn option:

const { user } = await withAuth({ ensureSignedIn: true });

Enabling ensureSignedIn will redirect users to AuthKit if they attempt to access the page without being authenticated.

Middleware auth

The default behavior of this library is to request authentication via the withAuth method on a per-page basis. There are some use cases where you don't want to call withAuth (e.g. you don't need user data for your page) or if you'd prefer a "secure by default" approach where every route defined in your middleware matcher is protected unless specified otherwise. In those cases you can opt-in to use middleware auth instead:

import { authkitMiddleware } from '@workos-inc/authkit-nextjs';

export default authkitMiddleware({
  middlewareAuth: {
    enabled: true,
    unauthenticatedPaths: ['/', '/about'],
  },
});

// Match against pages that require auth
// Leave this out if you want auth on every resource (including images, css etc.)
export const config = { matcher: ['/', '/admin/:path*', '/about'] };

In the above example the /admin page will require a user to be signed in, whereas / and /about can be accessed without signing in.

unauthenticatedPaths uses the same glob logic as the Next.js matcher.

Retrieve session in middleware

Sometimes it's useful to check the user session if you want to compose custom middleware. The getSession helper method will retrieve the session from the cookie and verify the access token.

import { authkitMiddleware, getSession } from '@workos-inc/authkit-nextjs';
import { NextRequest, NextFetchEvent } from 'next/server';

export default async function middleware(request: NextRequest, event: NextFetchEvent) {
  // authkitMiddleware will handle refreshing the session if the access token has expired
  const response = await authkitMiddleware()(request, event);

  // If session is undefined, the user is not authenticated
  const session = await getSession(response);

  // ...add additional middleware logic here

  return response;
}

// Match against pages that require auth
export const config = { matcher: ['/', '/account/:path*'] };

Signing out

Use the signOut method to sign out the current logged in user and redirect to your app's homepage. The homepage redirect is set in your WorkOS dashboard settings under "Redirect".

Visualizing an impersonation

Render the Impersonation component in your app so that it is clear when someone is impersonating a user. The component will display a frame with some information about the impersonated user, as well as a button to stop impersonating.

import { Impersonation } from '@workos-inc/authkit-nextjs';

export default function App() {
  return (
    <div>
      <Impersonation />
      {/* Your app content */}
    </div>
  );
}

Get the access token

Sometimes it is useful to obtain the access token directly, for instance to make API requests to another service.

import { withAuth } from '@workos-inc/authkit-nextjs';

export default async function HomePage() {
  const { accessToken } = await withAuth();

  if (!accessToken) {
    return <div>Not signed in</div>;
  }

  const serviceData = await fetch('/api/path', {
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  });

  return <div>{serviceData}</div>;
}

Refreshing the session

Use the refreshSession method in a server action or route handler to fetch the latest session details, including any changes to the user's roles or permissions.

The organizationId parameter can be passed to refreshSession in order to switch the session to a different organization. If the current session is not authorized for the next organization, an appropriate authentication error will be returned.

Sign up paths

The signUpPaths option can be passed to authkitMiddleware to specify paths that should use the 'sign-up' screen hint when redirecting to AuthKit. This is useful for cases where you want a path that mandates authentication to be treated as a sign up page.

import { authkitMiddleware } from '@workos-inc/authkit-nextjs';

export default authkitMiddleware({
  signUpPaths: ['/account/sign-up', '/dashboard/:path*'],
});

Debugging

To enable debug logs, initialize the middleware with the debug flag enabled.

import { authkitMiddleware } from '@workos-inc/authkit-nextjs';

export default authkitMiddleware({ debug: true });

Troubleshooting

NEXT_REDIRECT error when using try/catch blocks

Wrapping a withAuth({ ensureSignedIn: true }) call in a try/catch block will cause a NEXT_REDIRECT error. This is because withAuth will attempt to redirect the user to AuthKit if no session is detected and redirects in Next must be called outside a try/catch.