Authentication library for Next.js applications with support for OAuth, email, and credentials authentication
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Built-in support for 67+ authentication providers including OAuth, email, and credentials-based authentication. NextAuth.js provides extensive provider ecosystem with standardized configuration patterns.
NextAuth.js supports three main types of authentication providers with different use cases and configurations.
/**
* Base provider interface for all authentication providers
*/
interface Provider extends CommonProviderOptions {
id: string;
name: string;
type: ProviderType;
options?: any;
}
interface CommonProviderOptions {
id: string;
name: string;
type: ProviderType;
options?: any;
}
type ProviderType = "oauth" | "email" | "credentials";OAuth providers for third-party authentication services with standardized configuration.
/**
* OAuth provider configuration interface
*/
interface OAuthConfig<P> extends CommonProviderOptions {
id: string;
name: string;
type: "oauth";
/** OAuth authorization endpoint or handler */
authorization: string | AuthorizationEndpointHandler;
/** OAuth token endpoint or handler */
token: string | TokenEndpointHandler;
/** OAuth userinfo endpoint or handler */
userinfo?: string | UserinfoEndpointHandler;
/** OpenID Connect well-known configuration URL */
wellKnown?: string;
/** OAuth client configuration */
client: Partial<ClientMetadata>;
/** OAuth client ID */
clientId: string;
/** OAuth client secret */
clientSecret: string;
/** ID token support flag */
idToken?: boolean;
/** OAuth provider style configuration */
style?: ProviderStyleConfig;
/** Custom profile mapping function */
profile?: (profile: P, tokens: TokenSet) => Awaitable<User>;
/** Additional OAuth options */
options?: OAuthUserConfig<P>;
}
interface OAuthUserConfig<P> {
clientId: string;
clientSecret: string;
authorization?: string | AuthorizationEndpointHandler;
token?: string | TokenEndpointHandler;
userinfo?: string | UserinfoEndpointHandler;
wellKnown?: string;
issuer?: string;
client?: Partial<ClientMetadata>;
profile?: (profile: P, tokens: TokenSet) => Awaitable<User>;
style?: ProviderStyleConfig;
options?: any;
}Usage Examples:
// Google OAuth Provider
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
],
});
// GitHub OAuth Provider with custom profile
import GitHubProvider from "next-auth/providers/github";
export default NextAuth({
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID!,
clientSecret: process.env.GITHUB_SECRET!,
profile(profile) {
return {
id: profile.id.toString(),
name: profile.name || profile.login,
email: profile.email,
image: profile.avatar_url,
username: profile.login,
};
},
}),
],
});
// Auth0 Provider with custom domain
import Auth0Provider from "next-auth/providers/auth0";
export default NextAuth({
providers: [
Auth0Provider({
clientId: process.env.AUTH0_CLIENT_ID!,
clientSecret: process.env.AUTH0_CLIENT_SECRET!,
issuer: process.env.AUTH0_ISSUER_BASE_URL,
authorization: {
params: {
scope: "openid email profile",
audience: process.env.AUTH0_AUDIENCE,
},
},
}),
],
});Email-based passwordless authentication with magic link functionality.
/**
* Email provider configuration interface
*/
interface EmailConfig extends CommonProviderOptions {
id: string;
name: string;
type: "email";
/** Email server configuration */
server: string | EmailServerConfig;
/** Sender email address */
from: string;
/** Maximum age for verification tokens in seconds */
maxAge?: number;
/** Custom email sending function */
sendVerificationRequest?: (params: {
identifier: string;
url: string;
expires: Date;
provider: EmailConfig;
token: string;
theme: Theme;
request: Request;
}) => Awaitable<void>;
/** Generate custom verification token */
generateVerificationToken?: () => Awaitable<string>;
/** Normalize email address */
normalizeIdentifier?: (identifier: string) => string;
/** Email provider options */
options?: EmailUserConfig;
}
interface EmailServerConfig {
host: string;
port: number;
auth: {
user: string;
pass: string;
};
secure?: boolean;
tls?: {
ciphers?: string;
rejectUnauthorized?: boolean;
};
}
interface EmailUserConfig {
server: string | EmailServerConfig;
from: string;
maxAge?: number;
sendVerificationRequest?: (params: any) => Awaitable<void>;
generateVerificationToken?: () => Awaitable<string>;
normalizeIdentifier?: (identifier: string) => string;
}Usage Examples:
// Basic email provider with SMTP
import EmailProvider from "next-auth/providers/email";
export default NextAuth({
providers: [
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD,
},
},
from: process.env.EMAIL_FROM,
}),
],
});
// Email provider with custom verification
export default NextAuth({
providers: [
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
maxAge: 24 * 60 * 60, // 24 hours
sendVerificationRequest: async ({ identifier, url, provider }) => {
// Custom email sending logic
await sendCustomVerificationEmail({
to: identifier,
verificationUrl: url,
provider,
});
},
}),
],
});
// Email provider with custom domain normalization
export default NextAuth({
providers: [
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
normalizeIdentifier: (identifier: string) => {
// Custom email normalization
return identifier.toLowerCase().trim();
},
}),
],
});Username/password authentication with custom validation logic.
/**
* Credentials provider configuration interface
*/
interface CredentialsConfig extends CommonProviderOptions {
id: string;
name: string;
type: "credentials";
/** Form field definitions */
credentials: Record<string, CredentialInput>;
/** Custom authorization function */
authorize: (
credentials: Record<string, string> | undefined,
req: Pick<RequestInternal, "body" | "query" | "headers" | "method">
) => Awaitable<User | null>;
/** Credentials provider options */
options?: CredentialsUserConfig;
}
interface CredentialInput {
/** Input field label */
label?: string;
/** Input field type */
type?: string;
/** Input field placeholder */
placeholder?: string;
/** Default input value */
value?: string;
}
interface CredentialsUserConfig {
name?: string;
credentials: Record<string, CredentialInput>;
authorize: (
credentials: Record<string, string> | undefined,
req: any
) => Awaitable<User | null>;
}Usage Examples:
// Basic credentials provider
import CredentialsProvider from "next-auth/providers/credentials";
export default NextAuth({
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
// Validate credentials against your database
const user = await validateUser(credentials?.username, credentials?.password);
if (user) {
return {
id: user.id,
name: user.name,
email: user.email,
};
}
return null;
}
})
],
});
// Advanced credentials provider with multiple fields
export default NextAuth({
providers: [
CredentialsProvider({
name: "Company Login",
credentials: {
email: {
label: "Email",
type: "email",
placeholder: "user@company.com"
},
password: {
label: "Password",
type: "password"
},
domain: {
label: "Domain",
type: "text",
placeholder: "company.com"
},
},
async authorize(credentials, req) {
// Custom validation with multiple fields
const user = await validateCompanyUser({
email: credentials?.email,
password: credentials?.password,
domain: credentials?.domain,
});
if (user) {
return {
id: user.id,
name: user.name,
email: user.email,
domain: user.domain,
};
}
throw new Error("Invalid credentials");
}
})
],
});
// API-based credentials validation
export default NextAuth({
providers: [
CredentialsProvider({
name: "API Login",
credentials: {
apiKey: { label: "API Key", type: "password" },
userId: { label: "User ID", type: "text" },
},
async authorize(credentials, req) {
// Validate against external API
const response = await fetch("https://api.example.com/validate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
apiKey: credentials?.apiKey,
userId: credentials?.userId,
}),
});
const result = await response.json();
if (response.ok && result.valid) {
return {
id: result.user.id,
name: result.user.name,
email: result.user.email,
apiAccess: true,
};
}
return null;
}
})
],
});NextAuth.js includes 67+ built-in OAuth providers with pre-configured settings.
/**
* Selection of popular built-in OAuth providers
*/
interface PopularOAuthProviders {
Apple: typeof AppleProvider;
Auth0: typeof Auth0Provider;
AzureAD: typeof AzureADProvider;
Cognito: typeof CognitoProvider;
Discord: typeof DiscordProvider;
Facebook: typeof FacebookProvider;
GitHub: typeof GitHubProvider;
GitLab: typeof GitLabProvider;
Google: typeof GoogleProvider;
LinkedIn: typeof LinkedInProvider;
Okta: typeof OktaProvider;
Spotify: typeof SpotifyProvider;
Twitch: typeof TwitchProvider;
Twitter: typeof TwitterProvider;
}Usage Examples:
// Multiple OAuth providers
import GoogleProvider from "next-auth/providers/google";
import GitHubProvider from "next-auth/providers/github";
import DiscordProvider from "next-auth/providers/discord";
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
GitHubProvider({
clientId: process.env.GITHUB_ID!,
clientSecret: process.env.GITHUB_SECRET!,
}),
DiscordProvider({
clientId: process.env.DISCORD_CLIENT_ID!,
clientSecret: process.env.DISCORD_CLIENT_SECRET!,
}),
],
});
// Apple Sign In with custom configuration
import AppleProvider from "next-auth/providers/apple";
export default NextAuth({
providers: [
AppleProvider({
clientId: process.env.APPLE_ID!,
clientSecret: process.env.APPLE_SECRET!,
authorization: {
params: {
scope: "name email",
response_mode: "form_post",
},
},
}),
],
});
// Azure AD with tenant configuration
import AzureADProvider from "next-auth/providers/azure-ad";
export default NextAuth({
providers: [
AzureADProvider({
clientId: process.env.AZURE_AD_CLIENT_ID!,
clientSecret: process.env.AZURE_AD_CLIENT_SECRET!,
tenantId: process.env.AZURE_AD_TENANT_ID,
authorization: {
params: {
scope: "openid profile email User.Read",
},
},
}),
],
});Advanced patterns for creating custom providers and extending existing ones.
/**
* Custom provider creation utilities
*/
interface CustomProviderConfig {
/** Create custom OAuth provider */
createOAuthProvider: <P>(config: OAuthUserConfig<P>) => OAuthConfig<P>;
/** Extend existing provider */
extendProvider: <T extends Provider>(provider: T, overrides: Partial<T>) => T;
/** Create provider with custom endpoints */
createCustomProvider: (endpoints: CustomEndpoints) => Provider;
}
interface CustomEndpoints {
authorization: string;
token: string;
userinfo: string;
issuer?: string;
}Usage Examples:
// Custom OAuth provider
const CustomProvider = {
id: "custom-oauth",
name: "Custom OAuth Service",
type: "oauth",
authorization: "https://oauth.example.com/authorize",
token: "https://oauth.example.com/token",
userinfo: "https://oauth.example.com/userinfo",
clientId: process.env.CUSTOM_CLIENT_ID,
clientSecret: process.env.CUSTOM_CLIENT_SECRET,
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
};
},
};
// Extend existing provider
import GoogleProvider from "next-auth/providers/google";
const ExtendedGoogleProvider = {
...GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
authorization: {
params: {
scope: "openid email profile https://www.googleapis.com/auth/calendar.readonly",
prompt: "consent",
access_type: "offline",
response_type: "code",
},
},
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
locale: profile.locale,
};
},
};
// Provider with custom token handling
const CustomTokenProvider = {
id: "custom-token",
name: "Custom Token Provider",
type: "oauth",
authorization: "https://auth.example.com/oauth/authorize",
token: {
url: "https://auth.example.com/oauth/token",
async request({ client, params, checks, provider }) {
// Custom token request logic
const response = await client.oauthCallback(
provider.callbackUrl,
params,
checks
);
// Custom token processing
return {
tokens: response,
profile: await fetchCustomProfile(response.access_token),
};
},
},
userinfo: "https://api.example.com/user",
clientId: process.env.CUSTOM_CLIENT_ID,
clientSecret: process.env.CUSTOM_CLIENT_SECRET,
};
export default NextAuth({
providers: [
CustomProvider,
ExtendedGoogleProvider,
CustomTokenProvider,
],
});Configuration options for customizing provider appearance in sign-in pages.
/**
* Provider styling configuration
*/
interface ProviderStyleConfig {
/** Provider logo URL */
logo?: string;
/** Provider logo dark mode URL */
logoDark?: string;
/** Provider background color */
bg?: string;
/** Provider background dark mode color */
bgDark?: string;
/** Provider text color */
text?: string;
/** Provider text dark mode color */
textDark?: string;
}Usage Example:
// Custom provider styling
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
style: {
logo: "https://example.com/google-logo.png",
bg: "#4285f4",
text: "#fff",
bgDark: "#1a73e8",
textDark: "#fff",
},
}),
],
});interface AuthorizationEndpointHandler {
url: string;
params?: Record<string, string>;
request?: (context: any) => Awaitable<any>;
}
interface TokenEndpointHandler {
url: string;
params?: Record<string, string>;
request?: (context: any) => Awaitable<any>;
}
interface UserinfoEndpointHandler {
url: string;
params?: Record<string, string>;
request?: (context: any) => Awaitable<any>;
}
interface ClientMetadata {
client_id?: string;
client_secret?: string;
redirect_uris?: string[];
response_types?: string[];
grant_types?: string[];
application_type?: string;
contacts?: string[];
client_name?: string;
logo_uri?: string;
client_uri?: string;
policy_uri?: string;
tos_uri?: string;
jwks_uri?: string;
jwks?: any;
software_id?: string;
software_version?: string;
}
interface TokenSet {
access_token: string;
expires_at?: number;
id_token?: string;
refresh_token?: string;
scope?: string;
session_state?: string;
token_type?: string;
}interface RequestInternal {
body?: any;
query?: any;
headers?: any;
method?: string;
cookies?: any;
url?: string;
}
interface Theme {
colorScheme?: "light" | "dark" | "auto";
logo?: string;
brandColor?: string;
buttonText?: string;
}