after entering correct email and password combination i can see the user in the server console which means it is correctly returning the user but after the signin the response i get in the console is:
POST http://localhost:3000/api/auth/callback/credentials 403 (Forbidden)
{error: 'AccessDenied', status: 403, ok: false, url: null}
pls try to Help me
I am trying to sign in the account with email and password which is saved in mongodb in format:
{
"_id": {
"$oid": "676d1d11309c3cdb5b8c37df"
},
"email": "akhildwivedi21092006@gmail.com",
"name": "Amit Dwivedi",
"isverified": true,
"age": "50",
"password": "yash"
}
But when i was entering right email and password i was getting an unusual behaviour in the client console:
POST http://localhost:3000/api/auth/callback/credentials 403 (Forbidden)
{error: 'AccessDenied', status: 403, ok: false, url: null}
i think someone more experienced could help me in this.
this is in api/auth/[...nextauth]/route.js:
import NextAuth from 'next-auth'
import GithubProvider from 'next-auth/providers/github'
import GoogleProvider from 'next-auth/providers/google'
import CredentialsProvider from 'next-auth/providers/credentials'
import clientPromise from '@/app/lib/clientprom'
export const authOptions = NextAuth({
providers: [
CredentialsProvider({
name: 'Credentials',
async authorize(credentials) {
let client = await clientPromise
const db = client.db()
const collection = db.collection('users')
const user = await collection.findOne({ email: credentials.email, password: credentials.password })
if (user) {
console.log(user)
return Promise.resolve(user)
} else {
return null // or throw new Error("Invalid credentials");
}
},
}),
GithubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
authorization: { params: { prompt: 'login' } },
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET
}),
],
callbacks: {
async signIn({ user, account, profile, email }) {
const client = await clientPromise
const db = client.db()
const collection = db.collection('users')
if (account.provider === 'google' || account.provider === 'github') {
let existingUser = await collection.findOne({ email: user.email, isverified: true })
if (existingUser) {
return true
} else {
await collection.insertOne({ email: user.email, name: profile.name, isverified: false })
return true
}
}
},
},
})
export { authOptions as GET, authOptions as POST }
and this is in login/page.js:
"use client";
import React, { useEffect ,useState} from "react";
import { signIn ,getCsrfToken} from "next-auth/react";
import { useForm } from "react-hook-form";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
const Login = () => {
const router = useRouter();
const [csrfToken, setCsrfToken] = useState("")
const {data:session} = useSession()
useEffect(() => {
const fetchCsrfToken = async () => {
const token = await getCsrfToken();
setCsrfToken(token);
};
fetchCsrfToken();
document.title = "Login - Get Me a Chai"
if (session) {
router.push("/createaccount");
}
}, [ session])
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm();
const onSubmit = async (data) => {
let response = await signIn("credentials", {
email: data.email,
password: data.password,
csrfToken,
redirect: false,
});
console.log(response)
}
const handleProviderSignIn = async (provider) => {
const response = await signIn(provider);
};
return (
<main className="flex">
<div className="w-1/2 p-10">
<div className="flex font-semibold text-[28px] leading-9 items-center"><p>Bittree</p> <img className="" width={22} src="greenlogo.svg" alt="" /></div>
<div className="flex items-center flex-col gap-4 py-10 mt-16">
<h1 className="font-extrabold text-[42px] leading-9 text-black">Sign Up or Log In</h1>
<p className="text-[#676b5f] font-normal">Welcome! Welcome! Welcome!</p>
</div>
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-4 px-10">
<div className="flex flex-col">
{errors.email && <span className="text-sm text-[#ff6b6b] font-semibold ">Please enter an email</span>}
<input
{...register("email", { required: true })}
type="text"
placeholder="Enter your Email*"
className="bg-[#f6f7f5] p-4 outline-none border rounded-lg border-[#9a9a9a]"
id="email"
/>
</div>
<div className="flex flex-col">
{errors.password && <span className="text-sm text-[#ff6b6b] font-semibold ">Please enter an Password</span>}
<input
{...register("password", { required: true })}
type="password"
placeholder="Enter your Password*"
className="bg-[#f6f7f5] p-4 outline-none border rounded-lg border-[#9a9a9a]"
/>
</div>
<button className="bg-[#8129d9] disabled:bg-[#8129d9c8] text-white p-3 font-semibold rounded-full" disabled={isSubmitting} type="submit">
Sign In
</button>
</form>
<p className="text-[#676b5f] font-normal text-center my-4">OR</p>
<div className="flex flex-col gap-3 px-10">
<button
onClick={() => handleProviderSignIn("google")}
type="button"
className="text-black bg-[white] justify-center hover:bg-[#f6f7f5] border font-bold rounded-full items-center hover:border-[#f6f7f5] px-5 py-2.5 text-center inline-flex dark:focus:ring-[#4285F4]/55 gap-2"
>
<img src="google.svg" alt="" />
Continue with Google
</button>
<button
onClick={() =>handleProviderSignIn("github")}
type="button"
className="text-white bg-[#24292F] justify-center hover:bg-[#24292F]/90 font-bold rounded-full gap-1 px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-gray-500 dark:hover:bg-[#050708]/30 me-2 mb-2"
>
<svg
className="w-4 h-4 me-2"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 .333A9.911 9.911 0 0 0 6.866 19.65c.5.092.678-.215.678-.477 0-.237-.01-1.017-.014-1.845-2.757.6-3.338-1.169-3.338-1.169a2.627 2.627 0 0 0-1.1-1.451c-.9-.615.07-.6.07-.6a2.084 2.084 0 0 1 1.518 1.021 2.11 2.11 0 0 0 2.884.823c.044-.503.268-.973.63-1.325-2.2-.25-4.516-1.1-4.516-4.9A3.832 3.832 0 0 1 4.7 7.068a3.56 3.56 0 0 1 .095-2.623s.832-.266 2.726 1.016a9.409 9.409 0 0 1 4.962 0c1.89-1.282 2.717-1.016 2.717-1.016.366.83.402 1.768.1 2.623a3.827 3.827 0 0 1 1.02 2.659c0 3.807-2.319 4.644-4.525 4.889a2.366 2.366 0 0 1 .673 1.834c0 1.326-.012 2.394-.012 2.72 0 .263.18.572.681.475A9.911 9.911 0 0 0 10 .333Z"
clipRule="evenodd"
/>
</svg>
Continue with Github
</button>
</div>
</div>
<div className="w-1/2 relative overflow-hidden"><img className="absolute translate-y-[-20%]" src="images/banner.png" alt="" /></div>
</main>
);
};
export default Login;
What a insteresting thing i am the one who asked this question and too i am answering this question:
So, i found out that i am not returning anything in signin callback and everything is just perfect. so i added this just after pervious condition of google and github:
if (account.provider === 'credential-provider') {
let existing user = await collection.findOne({email:user.email, password:userpassword)}
if (existingUser) {
return true
} else {
return false
}
}
and the problem is solved, hey stackoverflow if you wanna reach me you can find me by REACH ME this is my link created by my own Website