next-auth 4 session returns null, next.js
Asked Answered
H

1

0

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>
  )
}
Hyperemia answered 21/4, 2022 at 14:57 Comment(3)
I had series of issues with other parts. My set up is correct. I keep the question, it might help someone else with the setupHyperemia
If you ever get a chance, it might help to add an answer explaining how you fixed this, I am currently running into this issue, and being new to nextJS it is really holding me up. Happy coding!Naranjo
@RockwellRice I dont remember what was the issue exactly but it was not related to the setup. something that unrealted to auth set up, then because of that mustake, I had a bunch of other mistakes. I kept the question in case it helps other to set up next-auth4 in the futureHyperemia
V
1

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,
})};
Vannesavanness answered 23/4, 2022 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.