How to Use Auth.js in Astro
Auth.js (previously NextAuth) is a powerful authentication core library for JavaScript apps. Thanks to it’s framework-agnostic design & the auth-astro
framework adapter, it’s easier than ever to add authentication to your Astro site.
Setup
Create a new Astro project, or navigate to an existing one:
npm create astro@latest -- my-app --template minimal -y
Install a platform adapter (e.g. @astrojs/node
) to allow for server-side rendering:
npx astro add node
Install the unofficial Astro adapter & the core for Auth.js, along with a platform adapter for Astro (e.g. @astrojs/node
):
npm install @auth/core auth-astro
Navigate to astro.config.mjs
and import the auth-astro
adapter:
import { defineConfig } from 'astro/config';import node from "@astrojs/node";import auth from 'auth-astro';
export default defineConfig({ integrations: [ auth(), ], output: "server", adapter: node({ mode: "standalone" }),});
Create an auth.config.ts
configuration file in the root of your project:
export default { providers: [ // ... ],}
Configure Environment Variables
Signing Secret
Auth.js requires a secret to be set in order to sign the session cookie. This secret should be set to a random string of 32 characters. The documentation suggests on Linux, you generate one using openssl rand -hex 32
, or you can navigate to generate-secret.vercel.app to generate one in the browser.
NOTE For non-vercel deployments, you’ll need to set the
AUTH_TRUST_HOST
environment variable totrue
.
AUTH_SECRET=<your-secret>AUTH_TRUST_HOST=true
OAuth Providers
Next, we need to configure the authentication providers we want to use. For this demo, we’ll use GitHub. Go back to auth.config.ts
and add the following code:
NOTE You’ll need to set the
GITHUB_CLIENT_ID
andGITHUB_CLIENT_SECRET
environment variables in.env
. You can find out how to create a GitHub OAuth app here.
import GitHub from '@auth/core/providers/github'
export default { providers: [ GitHub({ clientId: import.meta.env.GITHUB_CLIENT_ID, clientSecret: import.meta.env.GITHUB_CLIENT_SECRET, }), ],}
Point your app’s redirect URL to [origin]/auth/callback/[provider]
depending on your provider. For example, if you’re using GitHub, your redirect URL should be [origin]/auth/callback/github
.
Signing In & Out
Now that we’ve configured Auth.js, we need to allow our users to sign in & out. Open src/pages/index.astro
and add the following code. This will render a sign in button if the user is not signed in, and a sign out button if they are. We get the session object from the Auth
component, and use it to determine which button to render.
---import type { Session } from '@auth/core/types';import { Auth, SignIn, SignOut } from 'auth-astro/components';---
<html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Astro</title> </head>
<body> <h1>Astro</h1> <Auth> {(session: Session) => { if (session) { return ( <> <p>Logged in as {session.user.name}</p> <SignOut>Sign Out</SignOut> </> ); } else { return <SignIn provider="github">Sign In</SignIn>; } }} </Auth> </body></html>
Protecting Routes
Now that we’ve got a sign in flow, we can add a protected route. Create a new file at src/pages/protected.astro
. We want to only allow signed in users to access this page, so we’ll use the getSession
server method to get the session object. If the user is not signed in, we’ll redirect them to the home page.
---import { getSession } from 'auth-astro/server';
let session = await getSession(Astro.request)if (!session) return Astro.redirect("/")---
<html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Astro</title> </head>
<body> <h1>Astro</h1> <p>Only signed in users can see this page.</p> </body></html>
Add a link to the protected page in src/pages/index.astro
to test it out:
<a href="/protected">Protected page</a>
That’s all!
With the new version of auth-astro
we’ve made it easier than ever to add authentication to your Astro site with as little effort as possible. If you have any questions, feel free to reach out to me on Discord or Twitter, or report any issues on GitHub.