/app/api/register/route.ts
import bcrypt from "bcrypt";
import prisma from "@/app/libs/prismadb";
import {NextApiResponse} from "next";
import {NextResponse} from "next/server";
export async function POST(request: Request, res: NextResponse) {
const body = await request.json();
const {email, name, password} = body;
const hashedPassword = await bcrypt.hash(password, 12);
const user = await prisma.user.create({
data: {
email,
name,
hashedPassword,
},
});
return user;
}
-我正在关注可能基于 NextJS 13.2 的教程。所以[...下一个] /pages/api/auth/[...nextauth].ts
import prisma from "@/app/libs/prismadb";
import {PrismaAdapter} from "@next-auth/prisma-adapter";
import NextAuth, {AuthOptions} from "next-auth";
import CredentialProvider from "next-auth/providers/credentials";
import bcrypt from "bcrypt";
import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
export const authOptions: AuthOptions = {
adapter: PrismaAdapter(prisma),
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID as string,
clientSecret: process.env.GITHUB_SECRET as string,
}),
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
CredentialProvider({
name: "credentials",
credentials: {
email: {label: "text", type: "text"},
password: {label: "password", type: "password"},
},
async authorize(credentials) {
if (!credentials?.email || !credentials?.password) {
throw new Error("Invalid credentials");
}
const user = await prisma.user.findUnique({
where: {
email: credentials?.email,
},
});
if (!user || !user?.hashedPassword) {
throw new Error("Invalid credentials");
}
const isCorrectPassword = await bcrypt.compare(
credentials.password,
user.hashedPassword
);
if (!isCorrectPassword) {
throw new Error("Invalid credentials");
}
// return undefined;
return user;
},
}),
],
pages: {
signIn: "/",
},
debug: process.env.NODE_ENV === "development",
session: {
strategy: "jwt",
},
secret: process.env.NEXTAUTH_SECRET,
};
export default NextAuth(authOptions);
/app/modal/RegisterModal.tsx
"use client";
import {AiFillGithub} from "react-icons/ai";
import axios from "axios";
import {FcGoogle} from "react-icons/fc";
import {useCallback, useState} from "react";
import {FieldValues, SubmitHandler, useForm} from "react-hook-form";
import useRegisterModal from "../hooks/useRegisterModal";
import Modal from "./Modal";
import Heading from "../components/Heading";
import {toast} from "react-hot-toast";
import {signIn} from "next-auth/react";
import Input from "../components/inputs/Input";
import Button from "../components/Button";
const RegisterModal = () => {
const registerModal = useRegisterModal();
const [isLoading, setIsLoading] = useState(false);
const {
register,
handleSubmit,
formState: {errors},
} = useForm<FieldValues>({
defaultValues: {
name: "",
email: "",
password: "",
},
});
const onSubmit: SubmitHandler<FieldValues> = (data) => {
setIsLoading(true);
axios
.post("/api/register", data)
.then(() => {
registerModal.onClose();
})
.catch((error) => toast.error("Some thing went wrong"))
.finally(() => setIsLoading(false));
};
const footerContent = (
<div className="flex flex-col gap-4 mt-3">
<hr />
<Button
outline
label="Continue with Google"
icon={FcGoogle}
onClick={() => {}}
/>
<Button
outline
label="Continue with Github"
icon={AiFillGithub}
onClick={() => {
signIn("github");
}}
/>
<div className=" justify-center text-neutral-500 text-center mt-4 font-light">
<div className="flex flex-row items-center gap-2">
<div>Already have an Account?</div>
<div
onClick={registerModal.onClose}
className="font-semibold text-neutral-800 cursor-pointer hover:underline"
>
Log in
</div>
</div>
</div>
</div>
);
const bodyContent = (
<div className="flex flex-col gap-4">
<Heading title="Welcome to Airbnb" subtitle="Create an Account" />
<Input
id="email"
label="Email"
disabled={isLoading}
register={register}
errors={errors}
required
/>
<Input
id="name"
label="Name"
disabled={isLoading}
register={register}
errors={errors}
required
/>
<Input
id="password"
label="Password"
type="password"
disabled={isLoading}
register={register}
errors={errors}
required
/>
</div>
);
return (
<Modal
disabled={isLoading}
isOpen={registerModal.isOpen}
title="Register"
actionLabel="Continue"
footer={footerContent}
onClose={registerModal.onClose}
onSubmit={handleSubmit(onSubmit)}
body={bodyContent}
/>
);
};
export default RegisterModal;
[下一个验证][调试][PROFILE_DATA]
[下一个验证][错误][OAUTH_CALLBACK_HANDLER_ERROR]
https://next-auth.js.org/errors#oauth_callback_handler_error getUserByAccount 不是函数 {
message: 'getUserByAccount 不是一个函数',
堆栈:'类型错误:getUserByAccount 不是函数
' +
' 在 Object.callback (D:\Web Dev Journey\NextJS irbnb
颂歌模块
外部自动