Issue with signIn('credentials') inside a Next.js Route Handler #12900
-
I’m working on a
import CredentialsProvider from 'next-auth/providers/credentials'
import { jwtCallback, sessionCallback } from './authCallbacks'
import { Credentials, SessionUser } from '@models/index'
import NextAuth, { User } from 'next-auth'
/**
* Función principal que configura NextAuth con el proveedor de credenciales personalizado.
*
* Configura:
* - Autenticación basada en JWT.
* - Provider de tipo `credentials` que acepta un accessToken, refreshToken y un `user` serializado.
* - Callbacks personalizados para gestionar JWT (`jwtCallback`) y sesión (`sessionCallback`).
*
* @returns Handlers, funciones `signIn`, `signOut` y `auth` exportables para uso global.
*/
export const { handlers, signIn, signOut, auth } = NextAuth({
secret: process.env.AUTH_SECRET,
session: {
strategy: 'jwt',
},
providers: [
CredentialsProvider({
name: '',
credentials: {
token: { label: 'Token', type: 'text' },
refreshToken: { label: 'Refresh Token', type: 'text' },
expiresIn: { label: 'Expires In', type: 'text' },
user: { label: 'User', type: 'text' },
},
/**
* Autoriza al usuario a través del proveedor de credenciales personalizado.
*
* Parsea el usuario desde `credentials.user`, valida que las credenciales mínimas existan
* y construye un objeto `User` que será utilizado por el callback `jwt()`.
*
* ⚠️ Se recomienda usar Zod/Joi para validar la estructura del objeto `user`.
*
* @param credentials Objeto con los campos enviados desde `signIn('credentials', {...})`
* @returns Usuario autenticado (formato compatible con NextAuth), o `null` si no es válido
*/
async authorize(credentials): Promise<User | null> {
console.log('🧪 [Authorize] Credenciales recibidas:', credentials)
const { token, refreshToken, expiresIn, user } = credentials as Credentials
if (!token || !refreshToken || !expiresIn || !user) {
console.error('❌ Falta uno o más campos requeridos:', { token, refreshToken, expiresIn, user })
return null
}
try {
const parsedUser: SessionUser = JSON.parse(user)
console.log('✅ Usuario parseado correctamente:', parsedUser)
console.log('🚀 Usuario final que se devuelve desde authorize():', {
...parsedUser,
access_token: token,
refresh_token: refreshToken,
expires_in: Number(expiresIn),
token_type: 'bearer',
})
return {
...parsedUser,
access_token: token,
refresh_token: refreshToken,
expires_in: Number(expiresIn),
token_type: 'bearer',
}
} catch (error) {
console.error('❌ Error al hacer JSON.parse(user):', error)
return null
}
},
}),
],
debug: process.env.NODE_ENV === 'development',
callbacks: {
jwt: jwtCallback,
session: sessionCallback,
},
})
... import { authToken, getUserData, signIn } from '@services/index'
import { NextResponse } from 'next/server'
export async function POST(req: Request) {
const { token } = await req.json()
if (!token) return NextResponse.json({ error: 'Token required' }, { status: 400 })
try {
const { access_token, refresh_token, expires_in } = await authToken(token)
const user = await getUserData(access_token)
console.log('📦 signIn payload:', {
token: access_token,
refreshToken: refresh_token,
expiresIn: expires_in.toString(),
user: JSON.stringify(user),
})
const res = await signIn('credentials', {
token: access_token,
refreshToken: refresh_token,
expiresIn: expires_in.toString(),
user: JSON.stringify(user),
redirect: false,
})
console.log('📦 res:', res) // ➡️ Only logs a URL, not a result object
if (!res?.ok) return NextResponse.json({ error: res.error }, { status: 401 })
return NextResponse.json({ ok: true })
} catch (error) {
console.error('Server login error:', error)
return NextResponse.json({ error: 'Server login failed' }, { status: 500 })
}
} 🔍 The issue Is it supported to call |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
As far as I know |
Beta Was this translation helpful? Give feedback.
-
You appear to be attempting to call signIn('credentials') inside a Next.js API route (or in a custom backend handler), but neither a session nor cookies are being created, and instead of returning an object with { ok, error } as you would anticipate from a server-side function, it is returning a URL string (such as http://localhost:3000/). This most likely happens because you are using signIn() in a non-client context (such as an API route), and NextAuth's behavior is designed to handle redirects rather than directly manage server-side sessions. Here are the key issues;
The best work around I would recommend is to Programmatically Handle Credentials Login on the Server. `` |
Beta Was this translation helpful? Give feedback.
You appear to be attempting to call signIn('credentials') inside a Next.js API route (or in a custom backend handler), but neither a session nor cookies are being created, and instead of returning an object with { ok, error } as you would anticipate from a server-side function, it is returning a URL string (such as http://localhost:3000/). This most likely happens because you are using signIn() in a non-client context (such as an API route), and NextAuth's behavior is designed to handle redirects rather than directly manage server-side sessions.
Here are the key issues;