Aura Auth
Guides

Aura Auth + Next.js

Build your first authentication flow with Aura Auth and Next.js

This guide walks you through creating a complete authentication flow using Aura Auth in a Next.js App Router application.

Overview

By the end of this guide, you'll have:

  • OAuth authentication with GitHub
  • Working sign-in and callback handlers

Install Aura Auth

If you haven’t installed the package yet:

npm install @aura-stack/auth

Set Up OAuth Provider

For this example, we'll use GitHub. First, create an OAuth App on GitHub:

  1. Go to GitHub Developer Settings
  2. Click "New OAuth App"
  3. Fill in the details:
    • Application name: Your app name
    • Homepage URL: http://localhost:3000 (for development)
    • Authorization callback URL: http://localhost:3000/auth/callback/github
  4. Save and copy your Client ID and Client Secret
For production deployments, update these URLs to match your production domain.

Configure Environment Variables

Create a .env file at the root of your project to store secrets securely. By convention, Aura Auth loads environment variables using the following pattern:

  • AURA_AUTH_{SERVICE}_CLIENT_ID
  • AURA_AUTH_{SERVICE}_CLIENT_SECRET
  • AURA_AUTH_SECRET (used internally for signing and encrypting session data)
.env
# 32-bytes (256-bit) secret used to sign/encrypt sessions. Use a secure random value.
AURA_AUTH_SECRET="base64-or-hex-32-bytes"

# OAuth Provider Credentials
AURA_AUTH_GITHUB_CLIENT_ID=your_github_client_id
AURA_AUTH_GITHUB_CLIENT_SECRET=your_github_client_secret
Never commit your .env file to version control. Use a secret manager in production.

For more detailed information about environment variables required by Aura Auth, see Environment Variables.

Create an Auth Configuration

Create an auth.ts file in your project to configure authentication. For more detailed information about createAuth, refer to the API Reference:

auth.ts
import { createAuth } from "@aura-stack/auth"

export const auth = createAuth({
  oauth: ["github"],
})

export const { handlers } = auth

This configuration enables GitHub as an OAuth provider and returns a set of ready-to-use HTTP handlers.

Integrate with Next.js (App Router)

Create a route to handle all authentication endpoints:

app/auth/[...auth]/route.ts
import { handlers } from "@/auth"

export const { GET, POST } = handlers

SignIn with Github

Start your development server and navigate to:

http://localhost:3000/auth/signIn/github

Next.js Implementation

app/signIn/page.tsx
const SignInPage = () => {
  return (
    <form action="auth/signIn/github">
      <button>SignIn with GitHub</button>
    </form>
  )
}

export default SignInPage

You'll be redirected to GitHub for authentication. After granting access, you'll be redirected back to your application, which will create cookies storing the sessionToken and csrfToken.

Get the Session

To verify authentication, check the session endpoint:

http://localhost:3000/auth/session

The cookies are sent to the handlers to verify the sessionToken cookie. Once the cookie is received by the endpoint, it's decrypted and verified to ensure the integrity of the token. There are two possible behaviors:

  • Valid Token: The JWT is decoded and the user session is returned via the Session type.
{
  "user": {
    "sub": "123",
    "name": "john doe",
    "email": "johndoe@gmail.com",
    "image": "johndoe.png"
  },
  "expires": "2026-1-05T14:48:00.000Z
}
  • Invalid Token: The sessionToken is revoked and returns an Unauthorized message
{
  "message": "Unnauthorized",
  "authenticated": false
}

Next.js Implementation.

import { cookies, headers } from "next/headers"

export const useAuth = async () => {
  const headersStore = new Headers(await headers())
  const cookiesStore = await cookies()
  headersStore.set("Cookie", cookiesStore.toString())
  const session = await fetch("http://localhost:3000/auth/session", {
    headers: headersStore,
    cache: "no-store",
  })
  const response = await session.json()
  return response as Session
}

SignOut the session

To sign out the current session, make a request to the sign-out endpoint.

http://localhost:3000/auth/signOut

The session is removed only when three conditions are met:

  • The sessionToken cookie must be present and valid.
  • The csrfToken cookie must be present and valid.
  • The X-CSRF-Token header must be present and equal to the value of the csrfToken cookie.

Once both conditions are satisfied, the following response is returned:

{ "message": "Signed out successfully" }

Next.js Implementation

server.ts
export const signOut = async () => {
  "use server"
  const csrf = await getCSRFToken()
  const cookieStore = await cookies()
  const signOutResponse = await fetch("http://localhost:3000/auth/signOut?token_type_hint=session_token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-CSRF-Token": csrf,
      Cookie: cookieStore.toString(),
    },
    body: JSON.stringify({}),
    cache: "no-store",
  })
  const response = await signOutResponse.json()
  if (signOutResponse.status === 202) {
    cookieStore.delete("aura-auth.sessionToken")
    cookieStore.delete("aura-auth.csrfToken")
    redirect("/")
  }
  return response
}
app/signOut/page.tsx
import { signOut } from "@/server"

const SignOutPage = () => {
  return (
    <form action={signOut}>
      <button>Sign Out</button>
    </form>
  )
}

export default SignOutPage

Available Routes

Aura Auth automatically sets up these routes:

RouteMethodDescription
/auth/signIn/:oauthGETInitiates the OAuth sign-in flow
/auth/sessionGETReturns the current user session
/auth/csrfTokenGETGet the CSRF Token to be used in /auth/signOut
/auth/signOutPOSTSign out the current session
All routes are relative to your base path (default: /auth)

Example Application

Check out our example applications for complete implementations:

On this page