NextAuth
This guide describes how to configure NextAuth.js to support authentication via OAuth2 and manage access tokens originating from gov.gr endpoints. It includes code examples and practical tips for secure integration.
Setting Up NextAuth for OAuth2 Token Management
This file contains a custom configuration of NextAuth.js using the credentials provider. It securely manages access/refresh tokens, extends JWTs, and organizes sessions for an OAuth2 flow.
Overview
The configuration:
- Uses
CredentialsProviderto manage customtokens(accessandrefresh). - Extends the
User,Token, andSession typesinNextAuthwith custom fields. - Stores
tokensin theJWTand handles their expiration. - Optionally configures
cookies(commented out).
Full Code with Explanations
Imports
import { addSeconds, getUnixTime } from "date-fns";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
addSecondsandgetUnixTimehelp compute expiration times.NextAuthis the main authentication function.CredentialsProviderhandles the custom login.
Type Extensions
declare module "next-auth" {
interface QueryParams {
access_token: string;
refresh_token: string;
role: string;
name: string;
afm: string;
}
interface User extends QueryParams {
id?: string;
}
interface Token extends QueryParams {
exp: number;
}
interface Session {
user: QueryParams;
}
}
Adds
afm,role,name, andtokensto theNextAuthtypes.
Credentials Provider Setup
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
access_token: { label: "Access Token", type: "text" },
refresh_token: { label: "Refresh Token", type: "text" },
role: { label: "Role", type: "text" },
first_name: { label: "First Name", type: "text" },
last_name: { label: "Last Name", type: "text" },
afm: { label: "AFM", type: "text" },
},
async authorize(credentials) {
if (!credentials?.access_token) {
console.error("No access token provided");
return null;
}
return {
access_token: credentials.access_token,
refresh_token: credentials.refresh_token,
role: credentials.role,
name: `${credentials.first_name} ${credentials.last_name}`,
afm: credentials.afm,
};
},
}),
],
- Defines fields for user input.
- Returns a complete user object for the
JWT.
Session & Pages Configuration
pages: {
signIn: "/",
},
session: {
strategy: "jwt",
maxAge: 60 * 60, // 1 hour
},
secret: process.env.NEXTAUTH_SECRET,
- Redirects to
/for login.- Uses
JWTwithout database-backedsessions.Session lifetimeis 1 hour.
JWT Callback
callbacks: {
async jwt({ token, user }) {
const now = getUnixTime(new Date());
if (user) {
token.access_token = user.access_token;
token.refresh_token = user.refresh_token;
token.role = user.role;
token.name = user.name;
token.afm = user.afm;
token.exp = getUnixTime(addSeconds(new Date(), 60 * 60)); // 1 hour
}
if (typeof token.exp === "number" && now > token.exp) {
delete token.access_token;
delete token.refresh_token;
delete token.role;
delete token.name;
delete token.afm;
delete token.exp;
}
return token;
},
- Stores data in the
tokenafterlogin.- Checks for expiration and removes sensitive fields.
Session Callback
async session({ session, token }) {
const now = getUnixTime(new Date());
if (typeof token.exp === "number" && now > token.exp) {
return { ...session, user: { ...session.user } }; // Έληξε το session
} else {
session.user = {
access_token: token.access_token as string,
refresh_token: token.refresh_token as string,
role: token.role as string,
name: token.name as string,
afm: token.afm as string,
};
}
return session;
},
},
- Copies the
tokeninto thesession.- Does not return expired
sessions.
Usage Example
After logging in through the OAuth2Login page, the provider:
- Receives the
tokenanduser info - Creates a
JWT - Populates the
sessionwith all necessary fields
Summary
This configuration enables secure login based on custom tokens with NextAuth in a Next.js application.
- Securely stores
tokens - Manages expiration
- Supports custom fields like
AFM,role, andname
