Context
I'm using NextJS v12.0.7
, React v17.0.2
, NextAuth v4.1.0
and Typescript v4.3.5
.
I wanted to create a simple auth system, based on NextAuth documentation and being redirected to homepage after logged in, so I've created a file in pages/api/auth
folder named [...nextauth].ts
that is containing these parts of code:
export default NextAuth({
providers: [
CredentialsProvider({
id: "credentials",
name: "Login",
credentials: {
username: { type: "email" },
password: { type: "password" },
},
async authorize(credentials) {
// [...]
},
}),
],
// [...]
callbacks: {
// [...]
redirect({ url, baseUrl }) {
console.log("redirect - url ", url, "baseUrl ", baseUrl); // This is what I was checking
if(url.startsWith(baseUrl)) {
return url
} else if(url.startsWith("/")) {
return new URL(url, baseUrl).toString();
}
return baseUrl;
}
},
})
For my NextJS project, I'm using a basepath /espace-personnel
defined in next.config.js
file, so I've defined NEXTAUTH_URL
in .env.local
file following the official NextAuth documentation :
NEXTAUTH_URL=http://localhost/espace-personnel/api/auth
My problem
Where I'm checking url
and baseUrl
variables in redirect callback, I can see that my NEXTAUTH_URL
variable isn't defined well, or I missunderstand something.
Here is the result of console.log("redirect - url ", url, "baseUrl ", baseUrl);
:
redirect - url http://localhost:3000 baseUrl http://localhost
I've done researches and I can't find any case like me on Google or Stackoverflow, I'm new in NextAuth so I'm probably misunderstanding something. Does someone have an idea of what I'm doing wrong ?
Edit (15/01/2022)
After thinking again about it, I've decided to check my env variable directly using process.env.NEXTAUTH_URL, so I've added that line after the previous console.log()
:
console.log("NEXTAUTH_URL", process.env.NEXTAUTH_URL)
And here is the result:
NEXTAUTH_URL http://localhost/espace-personnel/api/auth
So, in fact, this is not a problem of defining NEXTAUTH_URL, I think I misunderstand something about how NextAuth is working, I will continue to try to find a solution to my problem and share there if I'm finding something.
Edit (16/01/2022)
After some research, I've find that we can pass callbackUrl using signIn method, so I've defined my pages like that in [...nextauth].ts
:
pages: {
signIn: process.env.NEXT_PUBLIC_BASE_URL + '/connexion',
signOut: process.env.NEXT_PUBLIC_BASE_URL + '/deconnexion',
error: process.env.NEXT_PUBLIC_BASE_URL + '/connexion/erreur', // Error code passed in query string as ?error=
},
And here is the code of my login form :
import React, { useState } from "react";
import Alert from "../../ui/Alert/Alert";
import Button from "../../ui/Button/Button";
import Card from "../../ui/Card/Card";
import Divider from "../../ui/Divider/Divider";
import { getCsrfToken, signIn } from "next-auth/react";
import Input from "../../ui/Input/Input";
import styles from "./LoginForm.module.scss";
import Router from 'next/router';
type TAlertTitle = string;
type TAlertMessage = string;
type TAlertType = "info" | "warning" | "success" | "error";
export default function LoginForm({ csrfToken }: { csrfToken: string }) {
const [alertTitle, setAlertTitle] = useState<TAlertTitle>("Information");
const [alertMessage, setAlertMessage] = useState<TAlertMessage>("Juste un exemple");
const [alertType, setAlertType] = useState<TAlertType>("info");
async function onSubmit(event: React.SyntheticEvent<HTMLFormElement>) {
const target = event.target as typeof event.target & {
username: { value: string },
password: { value: string },
};
// Login attempt
const result = signIn('credentials', {
callbackUrl: process.env.NEXT_PUBLIC_BASE_URL,
username: target.username.value,
password: target.password.value
});
console.log(result);
event.preventDefault();
}
return (
<Card className={styles.card}>
<p className={'textSize40 fontWeightExtraBold textAlignCenter'}>
Connexion à votre espace personnel
</p>
<Divider className={styles.divider} />
<form onSubmit={onSubmit}>
<Alert title={alertTitle} message={alertMessage} type={alertType}></Alert>
<input name="csrfToken" type="hidden" defaultValue={csrfToken} />
<Input id="username" name="username" className="width100" type="email" autoComplete="email" placeholder="Adresse mail" leftIconLib="line-awesome" leftIcon="envelope" required />
<Input id="password" name="password" className="width100" type="password" autoComplete="current-password" placeholder="Mot de passe" leftIconLib="line-awesome" leftIcon="key" required />
<Button className="width100" theme="accent" type="submit">Se connecter</Button>
<Button className="width100" type="submit">Identifiants oubliés</Button>
</form>
</Card>
);
}
New problem is that when I'm trying to login, I'm redirected to http://localhost/api/auth/error
and I'm obtaining that error :
404 | This page could not be found.
Is there something I'm doing wrong there ?
NEXTAUTH_URL
, i.e.NEXTAUTH_URL=http://localhost:3000/espace-personnel/api/auth
? – Afternoons"dev": "next dev -p 80"
– Peoples