'Next Auth credentials sign in takes two submits
i'm trying to use next auth to setup a credentials sign in using email and password,the problem is whenever i try to sign in the (after i click submit button-sign in-) the page refresh and i don't get sign in until i re enter my email and password a second time and hit sign in on at the second time ,then i sign in im looping thgrouhs the providers because im using more than one
only credentials has this issue
code snippets:
{providers &&
Object.values(
providers as Record<string, ClientSafeProvider>,
).map((provider) => {
return provider.id === 'credentials' ? (
<EmailSignIn
provider={provider}
key={provider.name}
csrfToken={csrfToken ? csrfToken : ''}
/>
inside component EmailSignIn
const EmailSignIn = ({
csrfToken,
provider,
}: {
csrfToken: string
provider: ClientSafeProvider
}) => {
const router = useRouter()
const formElement = useRef(null)
const signInForm = useFormik({
initialValues: {
email: '',
password: '',
},
validationSchema: yup.object({
email: yup.string().email('must be a valid email').required(),
password: yup.string().required(),
}),
onSubmit: async (values) => {
;(formElement?.current as any).submit()
},
})
return (
<form
ref={formElement}
method="POST"
action={provider.callbackUrl}
onSubmit={signInForm.handleSubmit}
>
<div className="bg-white px-6 py-8 rounded shadow-md text-black w-full">
<input name="csrfToken" type="hidden" defaultValue={csrfToken} />
<input
type="text"
className="block border border-grey-light w-full p-3 rounded mb-4"
name="email"
id="email"
key={'email'}
placeholder="Email"
onBlur={signInForm.handleBlur}
onChange={signInForm.handleChange}
/>
{signInForm.touched.email && signInForm.errors.email ? (
<span
className="font-bold text-red-500 dark:text-red-500"
title={signInForm.errors.email as string}
>
* {signInForm.errors.email}
</span>
) : undefined}
<input
type="password"
key={'password'}
className="block border border-grey-light w-full p-3 rounded mb-4"
name="password"
id="password"
placeholder="Password"
onBlur={signInForm.handleBlur}
onChange={signInForm.handleChange}
/>
{signInForm.touched.password && signInForm.errors.password ? (
<span
className="font-bold text-red-500 dark:text-red-500"
title={signInForm.errors.password as string}
>
* {signInForm.errors.password}
</span>
) : undefined}
<button type="submit" className="btn btn-primary w-full">
Sign in
</button>
</div>
</form>
Inside [...nextauth].tsx credentials code snippet:
CredentialsProvider({
name: 'credentials',
type: 'credentials',
credentials: {
email: {
label: 'email',
type: 'input',
placeholder: 'email',
},
password: {
label: 'password',
type: 'input',
placeholder: 'password',
},
},
async authorize(credentials) {
const user = await prisma.user.findFirst({
where: {
email: credentials?.email,
},
})
if (
user &&
credentials?.password &&
bcrypt.compareSync(credentials.password, user.password as string)
) {
return {
id: user.id,
...credentials,
firstName: user.firstName,
lastName: user.lastName,
password: undefined,
}
}
// eslint-disable-next-line unicorn/no-null
return null
},
}),
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
