Reputation: 11
I am developing a next.js application, I use nextauth to manage the connection. I coded my api and my sql database.
When I connect and the credentials are correct, I have my API that interacts with my mysql database and returns a status 200 to indicate that the credentials are good but I do not have a redirection to my main page. Modifying the url directly does not seem to work either
here is my options.ts file in /app/api/auth/[...nextauth] :
import type { NextAuthOptions } from 'next-auth'; // Import the 'Profile' type from 'next-auth'
import GoogleProvider from 'next-auth/providers/google';
import CredentialsProvider from 'next-auth/providers/credentials';
import axios from 'axios';
import bcrypt from 'bcrypt';
import ChangePasswordDialog from '@/components/changePasswordDialog';
export const options: NextAuthOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
CredentialsProvider({
name: 'Credentials',
credentials: {},
async authorize(credentials) {
const { email, password } = credentials as { email: string, password: string };
console.log('Credentials :', credentials );
try {
const { data: users } = await axios.get(process.env.API_URL + 'utilisateurs/EmailsAndPasswords');
if (credentials) {
const user = users.find((user: any) => user.email === email);
if (user) {
const isMatch = await bcrypt.compare(password, user.password_hash);
console.log(user);
if (isMatch) {
return user;
} else {
return null;
}
} else {
return null;
}
}
console.log('Aucun credential fourni');
return null;
} catch (error) {
console.error('Erreur lors de l\'authentification:', error);
return null;
}
}
})
],
session: {
strategy: 'jwt', // Utiliser JWT pour gérer les sessions
maxAge: 30 * 60, // Durée de vie du token
},
jwt: {
secret: process.env.JWT_SECRET as string,
},
secret: process.env.JWT_SECRET as string,
callbacks: {
async signIn({ user, account, profile }) {
if (account && account.provider === 'google') {
if (!profile?.email) {
throw new Error('No email returned from Google');
}
const emailDomain = '@epfprojets.com';
if (profile.email.endsWith(emailDomain)) {
return true;
} else {
return false;
}
}
return true;
},
async jwt({ token, user }) {
if (user) {
token.id = user.id;
token.email = user.email;
token.name = user.name;
}
return token;
},
async session({ session, token }) {
session.user = {
email: token.email as string,
name: token.name as string,
};
return session;
},
async redirect({ url, baseUrl }: { url: string; baseUrl: string; }) {
return url.startsWith(baseUrl) ? url : baseUrl;
}
},
};
and here is the login page I created in /app/api/auth
"use client"
import Link from "next/link"
import { signIn } from "next-auth/react"
import {useSession} from "next-auth/react"
import { useState } from "react"
import { useRouter } from "next/navigation"
import { SessionProvider } from 'next-auth/react';
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"
export default function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const router = useRouter();
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const res = await signIn('credentials', {
email,
password,
redirect: false
});
if (res && res.error) {
setError("Email ou mot de passe incorrect");
}
} catch (error) {
console.log(error);
};
}
return (
<Card className="mx-auto max-w-sm">
<CardHeader>
<CardTitle className="text-2xl">Login</CardTitle>
<CardDescription>
Enter your email below to login to your account
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit}>
<div className="grid gap-4">
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="[email protected]"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="grid gap-2">
<div className="flex items-center">
<Label htmlFor="password">Password</Label>
<Link href="#" className="ml-auto inline-block text-sm underline">
Forgot your password?
</Link>
</div>
<Input id="password" type="password" required value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="By Quentin Dufour" />
</div>
{error && (
<div className="m-auto">
<Label htmlFor="error" className="bg-red-500 text-white w-fit text-sm py-1 px-3 rounded-md mt-2">
{error}
</Label>
</div>
)}
<Button type="submit" className="w-full">
Login
</Button>
<Separator className="h-[2px]"/>
<Button variant="outline" className="w-full">
Login with Google
</Button>
</div>
</form>
</CardContent>
</Card>
)
}
Here is my middleware.js:
export { default } from "next-auth/middleware";
I have several avenues that I am looking into without much conviction:
jwt: {
secret: process.env.JWT_SECRET as string,
},
secret: process.env.JWT_SECRET as string,
seem to be a source of the problem. When I comment out these lines, I can manually redirect to my main page by modifying the url after successful authentication.
Thank you for any help you can give me and for the time you will devote to my problem.
Upvotes: 0
Views: 53
Reputation: 4040
Redirect manually instead
import { useSearchParams, useRouter } from "next/navigation"
import { Route } from "@/routers/types"
export default function LoginForm() {
const router = useRouter()
const searchParams = useSearchParams()
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
const callbackUrl = searchParams.get("callbackUrl")
signIn("credentials", {
email,
password,
redirect: false
})
.then((res: SignInResponse | undefined) => {
if (!res.ok)
alert("Something went wrong")
else {
if (callbackUrl)
router.push(callbackUrl as Route)
else
router.push("/home")
}
})
}
}
Upvotes: 0