Help with NextAuth
Unanswered
Oriental chestnut gall wasp posted this in #help-forum
Oriental chestnut gall waspOP
I'm new to NextAuth and auth in general. I'm trying to set up a simple credentials-based sign in page. I am using Prisma as my db.
I have gotten as far as being able to create users with a username/password using a custom route, but I'm lost as far as how to authorize a user.
I am trying to use
Code examples in the comments
I have gotten as far as being able to create users with a username/password using a custom route, but I'm lost as far as how to authorize a user.
I am trying to use
next-auth/react/signin but I'm pretty sure I'm doing it wrong.Code examples in the comments
3 Replies
Oriental chestnut gall waspOP
api/auth/[...nextauth]/route.jsimport NextAuth from "next-auth";
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import CredentialsProvider from "next-auth/providers/credentials";
import prisma from "../../../../../lib/prisma";
export const authOptions = {
adapter: PrismaAdapter(prisma),
debug: true,
pages: { signIn: "/login" },
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" },
},
authorize: authorize(prisma),
}),
],
session: {
strategy: "jwt",
},
};
async function authorize(prisma) {
return async (credentials) => {
console.log(credentials);
console.log("i'm running the authorize function");
if (!credentials) throw new Error("Missing credentials");
if (!credentials.username)
throw new Error('"username" is required in credentials');
if (!credentials.password)
throw new Error('"password" is required in credentials');
const maybeUser = await prisma.user.findFirst({
where: { username: credentials.username },
select: { id: true, username: true, password: true },
});
if (!maybeUser || !maybeUser.password) return null;
const isValid = await compare(credentials.password, maybeUser.password);
if (!isValid) {
return null;
}
return { id: maybeUser.id, username: maybeUser.username };
};
}
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };api/user/loginimport prisma from "../../../../../lib/prisma";
import { hashPassword } from "../utils";
export default async function handle(req, res) {
if (req.method === "POST") {
//login uer
await loginUserHandler(req, res);
} else {
return res.status(405);
}
}
async function loginUserHandler(req, res) {
console.log("i'm running the loginUserHandler");
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: "invalid inputs" });
}
try {
const user = await prisma.user.findUnique({
where: { email: email },
select: {
id: true,
name: true,
email: true,
password: true,
image: true,
},
});
if (user && user.password === hashPassword(password)) {
// exclude password from json response
return res.status(200).json(exclude(user, ["password"]));
} else {
return res.status(401).json({ message: "invalid credentials" });
}
} catch (e) {
throw new Error(e);
}
}
// Function to exclude user password returned from prisma
function exclude(user, keys) {
for (let key of keys) {
delete user[key];
}
return user;
}app/login/page.js (relevant code only)"use client";
import { useState } from "react";
import { signIn } from "next-auth/react";
import Input from "@/components/Input";
import LabeledElement from "@/components/LabeledElement";
import Button from "@/components/Button";
export default function SignUpPage() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
async function handleSubmit(e) {
const signInResult = await signIn("credentials", {
username: username.toLowerCase(),
password: password,
redirect: false,
callbackUrl: "/dashboard",
});
console.log(signInResult);
}
...
}