nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
24.62k stars 3.46k forks source link

Invariant: headers() expects to have requestAsyncStorage, none available. || AuthJs "next-auth": "^5.0.0-beta.25" #12110

Closed Fabrice-Fabio closed 2 hours ago

Fabrice-Fabio commented 2 hours ago

Environment

System: OS: macOS 14.3.1 CPU: (10) arm64 Apple M1 Pro Memory: 82.78 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node Yarn: 1.22.22 - ~/node_modules/.bin/yarn npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm Browsers: Brave Browser: 129.1.70.119 Chrome: 130.0.6723.59 Safari: 17.3.1 npmPackages: next: 14.0.1 => 14.0.1 next-auth: ^5.0.0-beta.25 => 5.0.0-beta.25 react: 18 => 18.3.1

Reproduction URL

https://github.com/nextauthjs/next-auth-example

Describe the issue

I am using next-auth version 5.0.0-beta.25.

Workflow:

When I do a login and the user connects well with google auth, when he tries to make a request, it does not pass with: const session = await auth(); I am forced to use const session = await getSession();. On the other hand, if I keep const session = await getSession();. The user cannot log in the first time. So each time the user is connected, logically with const session = await auth(); , I should not have any problem, and my session should update automatically, which is not the case.

I am using version 5.0.0-beta.25 of next-auth.

When I sign in with google auth, it only works if my session is defined like this:

let axiosInstance = axios.create({
  baseURL: 'http://localhost:8080/',
  timeout: 10000,
});

axiosInstance.interceptors.request.use(async (config) => {
  const session = await auth();
  if (session) {
  config.headers["Authorization"] = "Bearer " + ${session.user.token};
}

return config;
});```

export default axiosInstance;

### How to reproduce

How to reproduce
// axios.ts

```js
let axiosInstance = axios.create({
  baseURL: 'http://localhost:8080/',
  timeout: 10000,
});

// Optional: Add interceptors for token handling, etc.
axiosInstance.interceptors.request.use(async (config) => {
const session = await auth();
console.log("session auth : ");
console.log(session);

if (session) {
  console.log("final session : "+session.user.token);
  config.headers["Authorization"] = "Bearer " + `${session.user.token}`;
}
return config;
});

export default axiosInstance;

// auth.js

export const { auth, handlers, signIn, signOut } = NextAuth({
    pages: {
    signIn: '/auth/login',
    signOut: '/auth/login'
},
session: {
strategy: "jwt",
},
providers: [
  Google({
    clientId: process.env.AUTH_GOOGLE_ID as string,
    clientSecret: process.env.AUTH_GOOGLE_SECRET as string,
    checks: ["none"],
    authorization: {
      params: {
        prompt: "consent",
        access_type: "offline",
        response_type: "code",
      },
    },
  }),
],
secret : process.env.AUTH_SECRET,
callbacks: {
      async signIn({ user }) {
        const userData = {
        name: user.name ?? "",
        email: user.email!,
        image: user.image ?? "",
        googleId: user.id,
      };

        try {
            console.log("step 1");
            const userService = new UserService();
            const createUserUseCase = new CreateUserUseCase(userService);

            let result = await createUserUseCase.execute(userData);
            console.log("xxx : ");
            console.log(result);
            if (result.token) {
                console.log("result.token : "+result.token);
                user.token = result.token;
            }
            return true;
        } catch (error) {
            console.error("User registration failed:", error);
            return false;
        }
    },
    async jwt({ token, user }) {
        console.log("jwt-token : ");
        console.log(token);
        console.log("jwt-user : ");
        console.log(user);
        if (user) {
            console.log("there ->");
            return {
                ...token,
                serverToken: user.token,
            };
        }
        return token;
    },
    async session({ session, token }) {
        console.log("session - in");
        console.log(token.serverToken);
        if (token) {
            session.user.token = token.serverToken as string;
        }

        console.log("-> : "+session.user.token);
        return session
    },
},
})

Expected behavior

The ideal and expected behavior is that in my axios.ts file.

I should not juggle between `const session = await auth(); andconst session = await getSession();` .

const session = await auth(); alone should be enough for the connection and the recovery of the current session to have the token that I pass to it in auth.js, which is not the case today.

github-actions[bot] commented 2 hours ago

We could not detect a valid reproduction link. Make sure to follow the bug report template carefully.

Why was this issue closed?

To be able to investigate, we need access to a reproduction to identify what triggered the issue. We need a link to a public GitHub repository. Example: (NextAuth.js example repository).

The bug template that you filled out has a section called "Reproduction URL", which is where you should provide the link to the reproduction.

What should I do?

Depending on the reason the issue was closed, you can do the following:

In general, assume that we should not go through a lengthy onboarding process at your company code only to be able to verify an issue.

My repository is private and cannot make it public

In most cases, a private repo will not be a sufficient minimal reproduction, as this codebase might contain a lot of unrelated parts that would make our investigation take longer. Please do not make it public. Instead, create a new repository using the templates above, adding the relevant code to reproduce the issue. Common things to look out for:

I did not open this issue, but it is relevant to me, what can I do to help?

Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps by opening a new issue.

I think my reproduction is good enough, why aren't you looking into it quickly?

We look into every issue and monitor open issues for new comments.

However, sometimes we might miss a few due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.

Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.

Useful Resources