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
Set Up OAuth Provider
For this example, we'll use GitHub. First, create an OAuth App on GitHub:
- Go to GitHub Developer Settings
- Click "New OAuth App"
- 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
- Save and copy your Client ID and Client Secret
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_IDAURA_AUTH_{SERVICE}_CLIENT_SECRETAURA_AUTH_SECRET(used internally for signing and encrypting session data)
# 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.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:
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
})
export const { handlers } = authThis 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:
import { handlers } from "@/auth"
export const { GET, POST } = handlersSignIn with Github
Start your development server and navigate to:
http://localhost:3000/auth/signIn/githubNext.js Implementation
const SignInPage = () => {
return (
<form action="auth/signIn/github">
<button>SignIn with GitHub</button>
</form>
)
}
export default SignInPageYou'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/sessionThe 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
sessionTokenis revoked and returns anUnauthorizedmessage
{
"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/signOutThe session is removed only when three conditions are met:
- The
sessionTokencookie must be present and valid. - The
csrfTokencookie must be present and valid. - The
X-CSRF-Tokenheader must be present and equal to the value of thecsrfTokencookie.
Once both conditions are satisfied, the following response is returned:
{ "message": "Signed out successfully" }Next.js Implementation
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
}import { signOut } from "@/server"
const SignOutPage = () => {
return (
<form action={signOut}>
<button>Sign Out</button>
</form>
)
}
export default SignOutPageAvailable Routes
Aura Auth automatically sets up these routes:
| Route | Method | Description |
|---|---|---|
/auth/signIn/:oauth | GET | Initiates the OAuth sign-in flow |
/auth/session | GET | Returns the current user session |
/auth/csrfToken | GET | Get the CSRF Token to be used in /auth/signOut |
/auth/signOut | POST | Sign out the current session |
/auth)Example Application
Check out our example applications for complete implementations:
- Next.js Example
- More examples coming soon!