SSR Quickstart Next.js
Doc type: Tutorial
Goal and expected outcome
Your Next.js app integrates with Yoyo Auth using a standard OAuth2 authorization code flow. You can choose one of two approaches:
- Cookie-based session (recommended for apps on
*.yoyogroup.comsubdomains): Validate shared cookies in middleware - Token-based session: Use OAuth to exchange tokens and set your own session
This guide covers both approaches.
Prerequisites and setup
- Your app is hosted on a subdomain of
*.yoyogroup.com(for cookie-based approach) or can handle OAuth callbacks (for token-based approach). - You can reach the hosted auth portal at
https://auth.yoyogroup.com. - You know the destination URL in your app that should receive the redirect back from auth.
- You have a registered OAuth2 client ID (for token-based approach).
Understanding the OAuth flow
Yoyo Auth uses a standard OAuth2 authorization code flow with credentialed OAuth providers (Google). The flow works as follows:
- User initiates authentication → redirect to hosted auth portal
- User authenticates via credentialed OAuth provider (Google)
- Auth portal redirects back to your app with authorization code (or sets cookies)
- Your app either validates cookies (cookie-based) or exchanges code for tokens (token-based)
Approach 1: Cookie-based session (recommended for *.yoyogroup.com subdomains)
Step 1: Redirect unauthenticated users to hosted auth
Add a middleware guard that checks the shared cookie and redirects to the auth portal when missing.
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const AUTH_PORTAL = 'https://auth.yoyogroup.com';
export function middleware(request: NextRequest) {
const token = request.cookies.get('yoyo_auth_access_token')?.value;
if (!token) {
const redirectUrl = encodeURIComponent(request.nextUrl.toString());
return NextResponse.redirect(`${AUTH_PORTAL}/?redirectUrl=${redirectUrl}`);
}
return NextResponse.next();
}
Step 2: Validate cookies in middleware
The middleware must validate cookies from the domain. Ensure your middleware validates the cookie before allowing access:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const AUTH_PORTAL = 'https://auth.yoyogroup.com';
export function middleware(request: NextRequest) {
const token = request.cookies.get('yoyo_auth_access_token')?.value;
// Validate the cookie exists and is from the correct domain
if (!token) {
const redirectUrl = encodeURIComponent(request.nextUrl.toString());
return NextResponse.redirect(`${AUTH_PORTAL}/?redirectUrl=${redirectUrl}`);
}
// Optionally validate token format or JWT claims server-side before allowing access
return NextResponse.next();
}
To fully trust the token contents, validate the JWT server-side using JWKS. For a complete example, see Validate JWTs with JWKS (Next.js).
Step 3: Read cookies server-side
Read the cookies in server components or route handlers and attach the access token to downstream API calls.
const accessToken = cookies().get('yoyo_auth_access_token')?.value;
if (accessToken) {
await fetch('https://api.yoyogroup.com/resource', {
headers: { Authorization: `Bearer ${accessToken}` }
});
}
Step 4: Handle logout
Redirect to the hosted logout endpoint to clear shared cookies.
https://auth.yoyogroup.com/logout?redirectUrl=<encoded return URL>
Approach 2: Token-based session (OAuth token exchange)
If you prefer to manage your own session or your app is not on a *.yoyogroup.com subdomain, use the OAuth flow to exchange tokens.
Step 1: Create an OAuth callback route
Create a route handler at /api/auth/callback (or your preferred path) to handle the OAuth callback:
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams;
const code = searchParams.get('code');
const state = searchParams.get('state');
if (!code) {
return NextResponse.json({ error: 'Missing authorization code' }, { status: 400 });
}
// Exchange the authorization code for tokens
const tokenResponse = await fetch('https://auth.yoyogroup.com/api/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: process.env.OAUTH_CLIENT_ID!,
redirect_uri: `${process.env.NEXT_PUBLIC_APP_URL}/api/auth/callback`,
code,
code_verifier: getCodeVerifierFromState(state), // Store verifier with state
}),
});
const tokens = await tokenResponse.json();
// Set your own session cookies or store tokens securely
const response = NextResponse.redirect('/');
response.cookies.set('session_token', tokens.access_token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: tokens.expires_in,
});
return response;
}
Step 2: Initiate OAuth flow
Redirect users to the OAuth authorization endpoint:
import { generateCodeVerifier, generateCodeChallenge } from '@/lib/oauth';
export async function initiateAuth() {
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
const state = generateState();
// Store code_verifier with state (e.g., in session or encrypted cookie)
storeCodeVerifier(state, codeVerifier);
const params = new URLSearchParams({
response_type: 'code',
client_id: process.env.OAUTH_CLIENT_ID!,
redirect_uri: `${process.env.NEXT_PUBLIC_APP_URL}/api/auth/callback`,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
state,
});
window.location.href = `https://auth.yoyogroup.com/api/oauth/authorize?${params}`;
}
Step 3: Validate your session in middleware
Validate your own session tokens in middleware:
export function middleware(request: NextRequest) {
const sessionToken = request.cookies.get('session_token')?.value;
if (!sessionToken) {
// Redirect to initiate OAuth flow
return NextResponse.redirect('/api/auth/login');
}
// Optionally validate token with auth portal
return NextResponse.next();
}
Verify the result
Cookie-based approach:
- Visit a protected route: you should be redirected to hosted auth, then back to your app.
- Confirm the
yoyo_auth_access_tokencookie exists on.yoyogroup.com.
Token-based approach:
- Visit a protected route: you should be redirected to OAuth authorization, then back to your callback.
- Confirm your session token is set and valid.
Example implementations
For complete working examples, see:
examples/yoyo-auth-nextjs-example- Next.js integration example with both cookie-based and token-based approaches- Local development quickstart - OAuth flow example for localhost
Next steps and links
- Work with shared cookies
- Handle redirects and allowlists
- GET /logout reference
- OAuth 2.0 Authentication
- Complete integration reference - Single-file reference for AI agents with all integration details