开发者问题收集

next-auth 4 会话返回 null,next.js

2022-04-21
7909

这是 api/auth/[...nextAuth].js 中的代码

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import User from "@/models/user";
import connectToDb from "@/config/dbConnection";
export default NextAuth({
  session: {
    strategy: "jwt",
  },
  providers: [
    CredentialsProvider({
      async authorize(credentials) {
        connectToDb();
        const { email, password } = credentials;
        // check if email and passwird entered
        if (!email || !password) {
          throw new Error("please enter email or password");
        }
        const user = await User.findOne({
          email,
          // becasue in pre.save I excluded returning password in api response
        }).select("+password");
        if (!user) {
          throw new Error("Invalid email or password");
        }
        // check if password is correct
        // I added comparePassword to userSchema methods in mongoose
        const isPasswordMatched = await user.comparePassword(password);
        if (!isPasswordMatched) {
          throw new Error("please enter email or password");
        }
        // creating a promise
        return Promise.resolve(user);
      },
    }),
  ],
  callbacks: {
    //   jwt callback is only called when token is created
    jwt: async ({ token, user }) => {
      // user is obj that we have received from authorize Promise.resolve(user)
      user && (token.user = user);
      // not this token has user property
      return Promise.resolve(token);
    },
    // user arg here is actully token that returned from jwt.
    session: async ({ session, token }) => {
      // session callback is called whenever a session for that particular user is checked
      console.log("user in ...next auth api", token);
      session.user = token.user;
      // since I get error, I return Promise.resolve(session)
      return Promise.resolve(session);
    },
  },
});

然后我编写了一个中间件来获取会话:

const isAuthenticatedUser = asyncErrors(async (req, res, next) => {
  // when user logged in we create the session of user
  // getSession gets auth-token from req.headers
  const session = await getSession({ req });
 // THIS RETURNS NULL
  console.log("session", session);
  if (!session) {
    return next(new ErrorHandler("Login first to access this resource", 401));
  }
  req.user = session.user;
  next();
});

export { isAuthenticatedUser };

我编写了 api/me 来检查用户

import nc from "next-connect";
import connectToDb from "@/config/dbConnection";

import { currentUserProfile } from "@/controllers/authController";

import { isAuthenticatedUser } from "@/middlewares/auth";
import onError from "@/middlewares/errors";

const handler = nc({ onError });

connectToDb();

handler.use(isAuthenticatedUser).get(currentUserProfile);

export default handler;

当我访问 http://localhost:3000/api/me 时,由于 session 记录为 null,因此我无法通过身份验证,即使在 chrome 调试工具的“应用程序”选项卡中存在 next-auth 凭据

由于 https://next-auth.js.org/getting-started/upgrade-v4

Version 4 makes using the SessionProvider mandatory.

这是 _app.js 组件

import { SessionProvider } from "next-auth/react"

export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    // `session` comes from `getServerSideProps` or `getInitialProps`.
    // Avoids flickering/session loading on first load.
    <SessionProvider session={session} refetchInterval={5 * 60}>
      <Component {...pageProps} />
    </SessionProvider>
  )
}
1个回答

发生此问题是因为未在登录按钮上指定 e.preventDefault()。

工作代码应如下所示:-

async function login(e) {
e.preventDefault(); //Add this to your code.

const getLoginStatus = await signIn("credentials", {
    redirect: false,
    username,
    password,
})};
CODING IN BLOOD
2022-04-23