Перенаправить после успешного входа в систему или зарегистрироваться для ввода учетных данных при следующей авторизации
Есть ли какие-либо примеры и / или способ перенаправления на личную панель управления при успешном входе в систему или регистрации для ввода учетных данных в
next-auth
? Я не мог найти никаких четких документов по этому поводу.
Я хотел добавить редирект ниже, но не был уверен, что это правильный подход:
callbacks.signIn = async (data, account, profile) => {
if ((account.provider === 'google' && profile.verified_email === true) || (account.type === 'credentials' && data.status === 200)) {
return Promise.resolve(true)
} else {
return Promise.resolve(false)
}
}
6 ответов
На самом деле это может произойти при инициации входа. Из документов вы можете передать URL-адрес обратного вызова для входа в систему. Ваш код будет выглядеть следующим образом.
signIn(provider.id, {
callbackUrl: `${window.location.origin}/protected`,
})
В новых версиях Next.js вы можете выполнить перенаправление метода getStaticProps следующим образом:
Ресурс: https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
export async function getStaticProps(context) {
// some imperative work..
//
if (!user) {
return {
redirect: {
destination: '/', // some destination '/dashboard' Ex,
permanent: false,
},
}
}
return {
props: {},
}
}
Использование пользовательского HTML
При использовании пользовательской страницы входа такое поведение недокументировано. Тем не менее, решение ниже работает для меня как шарм.
Чтобы внести ясность, другие ответы, связанные с параметром вsignIn
/signOut
функций достаточно, если вы их используете. См. документацию здесь для получения этих инструкций.
Этот ответ для тех, кто используетgetCsrfToken
в пользовательском запросе POST.
Используйте скрытое<input />
элемент
Ниже мы будем использовать скрытый элемент ввода для отправки POST-отправки формы.
Примечание. Далее предполагается, что вы правильно приобрели
csrfToken
.
<form
id="email-login"
method="post"
action="/api/auth/signin/email"
>
<input name="csrfToken" type="hidden" defaultValue={csrfToken} />
<input name="callbackUrl" type="hidden" defaultValue="/dashboard" />
<input
label="email"
id="email"
name="email"
type="email"
required
/>
<div>
<button
type="submit"
>
<span>
Email login
</span>
</button>
</div>
</form>
В приведенном выше фрагменте ключевой строкой является
<input name="callbackUrl" type="hidden" defaultValue="/dashboard" />
Это отправляетcallbackUrl
параметр body в запросе POST, чтобы вход перенаправлял пользователя наyour-site.tld/dashboard
.
у меня это работает вот так
"use client";
import Link from "next/link";
import { signIn } from "next-auth/react";
import { useState } from "react";
import { toast } from "react-toastify";
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
// handle submit event
const handleSubmit = async (e) => {
e.preventDefault();
try {
const isLoggedin = await signIn(
"credentials",
{
email,
password,
},
{ callbackUrl: "/dashboard/profile" }
);
if (isLoggedin.error !== null) {
toast.error("Incorrect Login Details!!");
} else {
toast.success("Login Successful!!");
// router.replace("/dashboard/profile");
}
} catch (error) {
toast.success(error);
}
};
return (
<div
style={{ maxWidth: "480px" }}
className="mt-10 mb-20 p-4 md:p-7 mx-auto rounded bg-white shadow-lg"
>
<form onSubmit={handleSubmit}>
<h2 className="mb-5 text-2xl font-semibold">Login</h2>
<div className="mb-4">
<label className="block mb-1"> Email </label>
<input
className="appearance-none border border-gray-200 bg-gray-100 rounded-md py-2 px-3 hover:border-gray-400 focus:outline-none focus:border-gray-400 w-full"
type="text"
placeholder="Type your email"
required
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="mb-4">
<label className="block mb-1"> Password </label>
<input
className="appearance-none border border-gray-200 bg-gray-100 rounded-md py-2 px-3 hover:border-gray-400 focus:outline-none focus:border-gray-400 w-full"
type="password"
placeholder="Type your password"
minLength={6}
required
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<button
type="submit"
className="my-2 px-4 py-2 text-center w-full inline-block text-white bg-blue-600 border border-transparent rounded-md hover:bg-blue-700"
>
Login
</button>
</form>
</div>
);
};
export default Login;
Проблема со встроеннымcallbackUrl in signIn
заключается в том, что он, похоже, перенаправляется, даже если ваши учетные данные неверны (по крайней мере, в моем случае)
Я думаю, что гораздо более простым и понятным подходом было бы установитьredirect: false
и самостоятельно обработать перенаправление с помощьюwindow.location.replace("...")
так:
function validate_login(event) {
event.preventDefault()
signIn("credentials", {
username: username_input.value,
password: password_input.value,
redirect: false, // this will prevent redirect
})
.then((result) => {
if (result?.error)
alert("Invalid Credentials!")
else
window.location.replace("/private_dashboard") // if login successful
})
.catch(err => {
...
})
.finally(() => {
...
})
}
Вот полный минимальный пример копирования и вставки, если вы ленивы, как я:
"use client"
import { signIn } from "next-auth/react";
function validate_login(event: any) {
event.preventDefault()
const username_inp: HTMLInputElement = document.querySelector("#username")!
const password_inp: HTMLInputElement = document.querySelector("#password")!
const submit_btn: HTMLInputElement = document.querySelector(`#submit_btn`)!
submit_btn.disabled = true
signIn("credentials", {
username: username_inp.value,
password: password_inp.value,
redirect: false,
})
.then((result) => {
if (result?.error)
alert("Invalid Credentials!")
else
window.location.replace("/user")
})
.catch(err => {
alert(`Error Occured: ${err}`)
})
.finally(() => {
submit_btn.disabled = false
})
}
const LoginPage = () => {
return (<form onSubmit={validate_login}>
<label>Username</label>
<input type="text" id="username" />
<br />
<br />
<label>Password</label>
<input type="password" id="password" />
<br />
<br />
<input id="submit_btn" type="submit" value="Submit"></input>
</form>)
}
export default LoginPage;
Примечание. Это было протестировано в Next.js 13.
Если вы перейдете к документации Next-Auth:https://next-auth.js.org/getting-started/client#signin
Вы обнаружите, что метод SignIn() принимает URL-адрес обратного вызова.
Это пример на основе версии, я использую версию 5.
V4
const url = await signIn(provider, { redirect: false, redirectTo: '/dashboard' })
V5
...
'use server'
const url = await signIn(provider, { redirect: false, redirectTo: '/dashboard'})
...
Также более подробную информацию вы можете найти внутри упаковки.
signIn<
P extends BuiltInProviderType | (string & {}),
R extends boolean = true
>(
/** Provider to sign in to */
provider?: P, // See: https://github.com/microsoft/TypeScript/issues/29729
options?: {
/** The URL to redirect to after signing in. By default, the user is redirected to the current page. */
redirectTo?: string
/** If set to `false`, the `signIn` method will return the URL to redirect to instead of redirecting automatically. */
redirect?: R
} & Record<string, any>,
authorizationParams?:
| string[][]
| Record<string, string>
| string
| URLSearchParams
): Promise<R extends false ? any : never>