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

发布于 2025-01-22 23:01:19 字数 3825 浏览 0 评论 0原文

这是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 Debugging Tools的Aplication Aplication aplication aplication aplication tab由于

https://next-auth.js.ss.org /启动/升级-V4

版本4使用SessionProvider强制性。

这是_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>
  )
}

This is code in 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);
    },
  },
});

then I write a middleware to get the 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 };

I write api/me to check the user

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;

When I visit http://localhost:3000/api/me, since session is logged as null, I get not authneticated, even though, in chrome debugging tools' Aplication tab next-auth credentials are present

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

Version 4 makes using the SessionProvider mandatory.

this is _app.js component

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>
  )
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯到世界奔溃 2025-01-29 23:01:19

由于未在登录按钮上指定e.preventdefault(),因此正在发生此问题。

工作代码应该看起来像: -

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

const getLoginStatus = await signIn("credentials", {
    redirect: false,
    username,
    password,
})};

This problem is happening due to not specifying e.preventDefault() on login button.

The working code should look like this :-

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

const getLoginStatus = await signIn("credentials", {
    redirect: false,
    username,
    password,
})};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文