Protect Server Actions
Learn how to protect your Server Actions so only authenticated users can execute them.
Server Actions bypass the Next.js middleware/proxy (and thus bypass our auth middleware), so you must perform authentication checks directly within the Server Action.
Create Server Action Auth Helper Function
First, add the requireServerActionAuth() function to your src/wristband.ts file. This function can be used to perform authentication checks within Server Actions.
// src/wristband.ts
import { NextRequest } from 'next/server';
import {
createWristbandAuth,
getReadOnlySessionFromCookies,
getSessionFromRequest,
NextJsCookieStore,
SessionOptions,
} from '@wristband/nextjs-auth';
export const wristbandAuth = createWristbandAuth({
clientId: '<WRISTBAND_CLIENT_ID>',
clientSecret: '<WRISTBAND_CLIENT_SECRET>',
wristbandApplicationVanityDomain: '<WRISTBAND_APPLICATION_VANITY_DOMAIN>',
});
const sessionOptions: SessionOptions = {
secrets: '<your-generated-secret>'
};
export function getRequestSession(request: NextRequest) {
return getSessionFromRequest(request, sessionOptions);
}
export const requireAuth = wristbandAuth.createMiddlewareAuth({
authStrategies: ['SESSION'],
sessionConfig: { sessionOptions, sessionEndpoint: '/api/auth/session' },
protectedPages: ['/', '/dashboard', '/settings(.*)'],
});
export function getServerComponentSession(cookieStore: NextJsCookieStore) {
return getReadOnlySessionFromCookies(cookieStore, sessionOptions);
}
// NEW: Helper function for performing authentication checkes within Server Actions.
export const requireServerActionAuth = wristbandAuth.appRouter.createServerActionAuth({
sessionOptions
});Add Authentication Checks to Server Actions
Use the requireServerActionAuth() helper function at the start of any Server Action that requires authentication. Calling this function returns a response that can be used to check if the user is authenticated. If the user is authenticated, it also returns their session.
// src/app/actions/fetch-tenant.ts
'use server';
import { cookies } from 'next/headers';
import { requireServerActionAuth } from 'src/wristband';
export async function fetchTenant() {
const cookieStore = await cookies();
const { authenticated, session } = await requireServerActionAuth(cookieStore);
// Check authentication
if (!authenticated) {
return { error: 'You are not authenticated. Please log in again.' };
}
// Access session data
const { accessToken, tenantId } = session;
// Make authenticated API call
const url = `https://${'your-wristband-app-vanity-domain'}/api/v1/tenants/${tenantId}`;
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
return { error: 'Failed to fetch tenant data.' };
}
const tenant = await response.json();
return { data: tenant };
}Updated 13 days ago
Next, let's protect your API routes so only authenticated requests can access them.