reactjs nextauth.js凭据提供程序:无法返回用户或错误消息

l7mqbcuq  于 2023-03-08  发布在  React
关注(0)|答案(2)|浏览(151)

我使用的是带有"凭据"的next-auth.js版本4.19.2(db)提供者和一些自定义登录, checkout 页面。我似乎无法返回它期望从授权()处理程序。我希望返回经过身份验证的用户或错误消息。我尝试了"返回用户"和"返回空值"以及解析和拒绝Promise "返回Promise. resolve"(用户)"和"返回承诺.拒绝(空)"...都不起作用。有人能发现下面的问题吗?谢谢!

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import GoogleProvider from "next-auth/providers/google";
import User from "../../../../models/User";

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    CredentialsProvider({
      name: "Credentials",

      async authorize(credentials, req) {
        const { username, password } = credentials;

        const user = await User.findOne({ email: username }).exec();

        if (user) {
          console.log("user", user);
          await user.comparePassword(password, function (err, isMatch) {
            console.log("comparePassword err, isMatch", err, isMatch);
            if (err) throw err;
            if (isMatch) {
              console.log("IS MATCH!");
              return Promise.resolve(user);
            }
          });
        } else {
          return Promise.reject(null);
        }
      },
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
  pages: {
    signIn: "/auth/signin",
    signOut: "/auth/signout",
    error: "/auth/error", // Error code passed in query string as ?error=
    verifyRequest: "/auth/verify-request", // (used for check email message)
    newUser: "/auth/new-user", // New users will be directed here on first sign in (leave the property out if not of interest)
  },
};

export default NextAuth(authOptions);

像这样使用它:

<button
  type="submit"
  className="btn btn-primary w-100 mt-4"
  onClick={() =>
    signIn("credentials", {
      redirect: false,
      username: state.username,
      password: state.password,
      callbackUrl: "/",
    }).then(({ ok, error }) => {
      if (ok) {
         alert("OK");
      } else {
         console.log(error);
         alert("NOT OK");
      }
    })
    }
   >
   Sign in
 </button>

我到底做错了什么?

vq8itlhq

vq8itlhq1#

你必须返回一个对象而不是一个承诺:

let returnedValue;

if (user) {
  await user.comparePassword(password, function (err, isMatch) {
    if (err) returnedValue = null; // throwing an error here will prevent the function from returning
    if (isMatch) returnedValue = user;
  });
} else {
  returnedValue = null;
}

return returnedValue;

同样,这里您只返回user,而不是将其存储在session中,为此您应该使用回调:

callbacks: {
 async jwt({ user, token }) {
   if (user) {
     token.user = user;
   }
   return token;
 },
 async session({ session, token }) {
   session.user = token.user;
   return session;
 },
},
wrrgggsh

wrrgggsh2#

这是我当前使用凭据的下一个身份验证,工作正常

import NextAuth from 'next-auth'
import GoogleProvider from "next-auth/providers/google";
import CredentialsProvider from "next-auth/providers/credentials"

import dbConnect from '../../../lib/dbConnect';
import User from '../../../models/User';
import { compare, hash } from 'bcryptjs';
import crypto from 'crypto';

import sendVerificationEmail from '../../../middleware/emailService';

let AuthUser;
export const authOptions = {
  providers: [
    // OAuth authentication providers...
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code"
        }
      }
    }),
    CredentialsProvider({
      name: 'Credentials',
      async authorize(credentials, req) {
        await dbConnect()
        
        //check user existance
        const result = await User.findOne({email: credentials.email}).select('+password')
        if(!result){
          throw new Error('No user Found With Email Please Sign Up!')
        }

        if(result.verified){
          //compare password
          const checkPassword = await compare(credentials.password, result.password)
          if(!checkPassword || result.email !== credentials.email){
            throw new Error("Email or Password dosen't match")
          }
          AuthUser = result
          return result
        }else{
          sendVerificationEmail(result.email, result.verificationToken)
          throw new Error("Please Confirm Your Email!")
        }

      }
    })
  ],
  callbacks:{
    signIn: async ({ user, account, profile }) => {
      await dbConnect()

      if (account.provider === "google") {
        const existingUser = await User.findOne({ email: user.email });

        if (existingUser) {
          AuthUser = existingUser
          return existingUser;
        }
        
        const randomPassword = crypto.randomBytes(8).toString('hex');

        const hashedPassword = await hash(randomPassword, 12);

        const newUser = await User.create({
          name: user.name,
          email:user.email,
          password:hashedPassword,
          provider:true,
          providerName:"google"
        });

        AuthUser = newUser
        return newUser;
      }else{
        return true
      }
    },
    session: async ({session}) => {

      if(AuthUser){
        // Add custom data to the session object
        session.userData = {
          isAdmin: AuthUser.isAdmin,
          id: AuthUser._id,
        };
      }
      return session;
    },
  },
  secret: process.env.NEXT_AUTH_SECRET,
  database: process.env.DB_URL  
}

export default NextAuth(authOptions)

相关问题