Refresh authentication cookies
next-firebase-auth-edge
provides two different functions to update user cookies after updating user credentials (eg. after setting new user claims).
Refresh auth cookies in Middleware
Use refreshNextResponseCookies
from next-firebase-auth-edge/lib/next/cookies
to refresh authentication cookies after updating user token in Next.js Middleware (opens in a new tab)
import { NextRequest } from "next/server";
import { refreshNextResponseCookies } from "next-firebase-auth-edge/lib/next/cookies";
import { getFirebaseAuth, authMiddleware } from "next-firebase-auth-edge";
const commonOptions = {
apiKey: 'XXxxXxXXXxXxxxxx_XxxxXxxxxxXxxxXXXxxXxX',
cookieName: "AuthToken",
cookieSignatureKeys: ["secret1", "secret2"],
cookieSerializeOptions: {
path: "/",
httpOnly: true,
secure: false, // Set this to true on HTTPS environments
sameSite: "strict" as const,
maxAge: 12 * 60 * 60 * 24, // twelve days
},
serviceAccount: {
projectId: 'your-firebase-project-id',
clientEmail: 'firebase-adminsdk-nnw48@your-firebase-project-id.iam.gserviceaccount.com',
privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n'
}
};
const { setCustomUserClaims, getUser } = getFirebaseAuth({
serviceAccount: commonOptions.serviceAccount,
apiKey: commonOptions.apiKey
});
export async function middleware(request: NextRequest) {
return authMiddleware(request, {
handleValidToken: async ({ decodedToken }, headers) => {
if (request.nextUrl.pathname === "/api/custom-claims") {
await setCustomUserClaims(decodedToken.uid, {
someClaims: ["someValue"],
});
const user = await getUser(decodedToken.uid);
const response = new NextResponse(JSON.stringify(user.customClaims), {
status: 200,
headers: { "content-type": "application/json" },
});
return refreshNextResponseCookies(request, response, commonOptions);
}
return NextResponse.next({
request: {
headers,
},
});
},
...commonOptions,
});
}
export const config = {
matcher: ["/", "/((?!_next|favicon.ico|api|.*\\.).*)", "/api/login", "/api/logout"],
};
Refresh auth cookies in API Route Handlers
Use refreshNextResponseCookies
from next-firebase-auth-edge/lib/next/cookies
to refresh authentication cookies after updating user token in API Route Handlers (opens in a new tab)
import { NextRequest, NextResponse } from "next/server";
import { refreshNextResponseCookies } from "next-firebase-auth-edge/lib/next/cookies";
import { getFirebaseAuth, getTokens } from "next-firebase-auth-edge";
const commonOptions = {
apiKey: 'XXxxXxXXXxXxxxxx_XxxxXxxxxxXxxxXXXxxXxX',
cookieName: "AuthToken",
cookieSignatureKeys: ["secret1", "secret2"],
cookieSerializeOptions: {
path: "/",
httpOnly: true,
secure: false, // Set this to true on HTTPS environments
sameSite: "strict" as const,
maxAge: 12 * 60 * 60 * 24, // twelve days
},
serviceAccount: {
projectId: 'your-firebase-project-id',
clientEmail: 'firebase-adminsdk-nnw48@your-firebase-project-id.iam.gserviceaccount.com',
privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n'
}
};
const { setCustomUserClaims, getUser } = getFirebaseAuth({
serviceAccount: commonOptions.serviceAccount,
apiKey: commonOptions.apiKey
});
export async function POST(request: NextRequest) {
const tokens = await getTokens(request.cookies, commonOptions);
if (!tokens) {
throw new Error("Cannot update custom claims of unauthenticated user");
}
await setCustomUserClaims(tokens.decodedToken.uid, {
someCustomClaim: {
updatedAt: Date.now(),
},
});
const user = await getUser(tokens.decodedToken.uid);
const response = new NextResponse(
JSON.stringify({
customClaims: user.customClaims,
}),
{
status: 200,
headers: { "content-type": "application/json" },
}
);
return refreshNextResponseCookies(request, response, commonOptions);
}
Refresh auth cookies in Pages Router API Routes
Use refreshApiResponseCookies
from next-firebase-auth-edge/lib/next/cookies
to refresh authentication cookies after updating user token in API Routes (opens in a new tab)
import { NextApiRequest, NextApiResponse } from "next";
import { refreshApiResponseCookies } from "next-firebase-auth-edge/lib/next/cookies";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
await refreshApiResponseCookies(req, res, {
serviceAccount: {
projectId: 'your-firebase-project-id',
clientEmail: 'firebase-adminsdk-nnw48@your-firebase-project-id.iam.gserviceaccount.com',
privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n'
},
apiKey: 'XXxxXxXXXxXxxxxx_XxxxXxxxxxXxxxXXXxxXxX',
cookieName: "AuthToken",
cookieSignatureKeys: ["secret1", "secret2"],
cookieSerializeOptions: {
path: "/",
httpOnly: true,
secure: false, // Set this to true on HTTPS environments
sameSite: "strict" as const,
maxAge: 12 * 60 * 60 * 24, // twelve days
},
});
res.status(200).json({ example: true });
}
Refresh auth cookies in Server Actions
Use refreshServerCookies
from next-firebase-auth-edge/lib/next/cookies
to refresh authentication cookies after updating user credential in Server Actions (opens in a new tab)
'use server';
import {cookies} from 'next/headers';
import {getTokens} from 'next-firebase-auth-edge';
import {refreshServerCookies} from 'next-firebase-auth-edge/lib/next/cookies';
const commonOptions = {
apiKey: 'XXxxXxXXXxXxxxxx_XxxxXxxxxxXxxxXXXxxXxX',
cookieName: "AuthToken",
cookieSignatureKeys: ["secret1", "secret2"],
cookieSerializeOptions: {
path: "/",
httpOnly: true,
secure: false, // Set this to true on HTTPS environments
sameSite: "strict" as const,
maxAge: 12 * 60 * 60 * 24, // twelve days
},
serviceAccount: {
projectId: 'your-firebase-project-id',
clientEmail: 'firebase-adminsdk-nnw48@your-firebase-project-id.iam.gserviceaccount.com',
privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n'
}
};
export async function performServerAction() {
const tokens = await getTokens(cookies(), commonOptions);
if (!tokens) {
throw new Error('Unauthenticated');
}
await refreshServerCookies(cookies(), commonOptions);
}