Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to prevent api/auth/session from being called multiple times? #6630

Closed
frontlearner28 opened this issue Feb 6, 2023 · 17 comments
Labels
question Ask how to do something or how something works

Comments

@frontlearner28
Copy link

Question 馃挰

Currently, I use getSession() in my Axios interceptor, to control valid session. The problem is that the session is being called multiple times on pages with many API calls, increasing my page load time too much.

Is there any way to prevent this?

CleanShot 2023-02-06 at 11 46 25

How to reproduce 鈽曪笍

To reproduce the problem, use getSession in an Axios interceptor and execute many calls on one page

Contributing 馃檶馃徑

Yes, I am willing to help answer this question in a PR

@frontlearner28 frontlearner28 added the question Ask how to do something or how something works label Feb 6, 2023
@balazsorban44
Copy link
Member

You should not use useSession for axios, as it's a React api. check out the getSession method instead.

@frontlearner28
Copy link
Author

@balazsorban44 but in my question I explained that I use getSession, at no point did I comment about useSession. Can you please reopen the issue? :c

@balazsorban44
Copy link
Member

balazsorban44 commented Feb 6, 2023

I need my glasses... 馃憖 This is likely still not a NextAuth.js bug for what it's worth, but how you use axios, I assume.

getSession is essentially just a json request to the /api/auth/session endpoint, it does no polling or the like.

@Ali-hd
Copy link

Ali-hd commented Dec 5, 2023

Hi @frontlearner28 I am facing the same issue as you, did you find out have you can reduce the api requests every time you use getSession() ?

@Ali-hd
Copy link

Ali-hd commented Dec 5, 2023

I need my glasses... 馃憖 This is likely still not a NextAuth.js bug for what it's worth, but how you use axios, I assume.

getSession is essentially just a json request to the /api/auth/session endpoint, it does no polling or the like.

Hi @balazsorban44 I understand that getSession is only used to get session info but is there a better way to use it? In client side I need to send the access token with many requests. With every request I need to call the method getSession() to get the Auth token, I don't have any other way in mind. Can I save the session data locally in the browser or something?

@patelmilanun
Copy link

@Ali-hd did u found any solution to this. @balazsorban44 can u suggest some better approach or link to something that can help here?

@balazsorban44
Copy link
Member

You can for example proxy the API requests through the Next.js backend and attach the session there. You can get the session server-side without extra network trips.

@patelmilanun
Copy link

Well actually, api/auth/session is basically the same. So from client side we are calling proxy api then it will be calling the api just like /api/auth/session as both of the things will be at next.js backend.

So either call api/auth/session and get token and then call the actual api or call the proxy api. I think in 2nd approch we can save 1 network trip from client side.

@patelmilanun
Copy link

TL;DR;
Use https://github.com/nextauthjs/next-auth-example/blob/main/app/client-example/page.tsx and set the "zustand" state in client component so in https://github.com/nextauthjs/next-auth-example/blob/main/components/client-example.tsx

So actually I was implementing it for 2 things. First is openapi-fetch client to attach auth on every request similar to axios and is already implemented using the getSession() which was causing the problem and cant make it hook as it might break and will have to do refactor since it is not react component. Second is to check permission access for specific function of application where I need to compare permission required to access that resource vs the session permissions.

So I ended up using state management library "zustand" note that u should not use it to share state across server component and client component. So using their official document for how to implement auth in client component (basically call auth() and get session, then take that session and pass it along with session provider which is wrapping the client component, and use useSession()). I used this trick on main layout file and then just in client component I set the state of zustand. This allowed me to access latest value of zustand state everywhere even in non-component file.

So u can implement this approach. Thanks for help guys!

@nghianguyen119
Copy link

I saw this issue after migrating to V5, but if it's the issue of next-auth then I can rest assured, the team need time to refactor

@mauricioleite1
Copy link

I'm using V5 and this keeps happening.. session and jwt callbacks happening 6 times one after another :/ I tried everything

@john-subba
Copy link

I'm using V5 and this keeps happening.. session and jwt callbacks happening 6 times one after another :/ I tried everything

Yeah. I am rethinking whether to use this or not. The session callback api get's called so many times. Even if i have not used useSession() hook

@HiroakiLion
Copy link

Having the same issue, for now I am caching the data I received to prevent multiple api calls based on useSession, but everytime i use useSession, the session calls are increasing rapidly.

@john-subba
Copy link

Having the same issue, for now I am caching the data I received to prevent multiple api calls based on useSession, but everytime i use useSession, the session calls are increasing rapidly.

i think if u use the session provider in specific components that u need u can tackle this issue even without caching it.
i previously wrapped everything with the provider in the layout.tsx maybe that was the reason it get's called multiple times.

@anshuopinion
Copy link

import { getBackendServerBaseUrlByEnvironment } from "@/utils/environmentUtil";
import axios from "axios";
import { getSession } from "next-auth/react";

// Singleton instance of Axios Auth Client
let axiosAuthClientInstance: ReturnType<typeof axiosAuthClient> | null = null;

/**
 * Get Axios Auth Client Instance
 * @dev - critical wrapper for handling api authorization to the backend
 *
 * Returns the singleton instance of the Axios Auth Client. If the instance
 * does not exist, it creates one.
 *
 * @returns {AxiosInstance} The singleton Axios instance.
 */
export const getAxiosAuthClientInstance = () => {
  if (!axiosAuthClientInstance) {
    axiosAuthClientInstance = axiosAuthClient();
  }
  return axiosAuthClientInstance;
};

/**
 * Axios Auth Client
 *
 * Creates an Axios instance configured to include the authorization token
 * from the NextAuth session in the request headers. This instance is created
 * once and reused throughout the application.
 *
 * @returns {AxiosInstance} The configured Axios instance.
 */
const axiosAuthClient = () => {
  const instance = axios.create({
    baseURL: getBackendServerBaseUrlByEnvironment(),
    headers: {
      "Content-Type": "application/json",
    },
  });

  instance.interceptors.request.use(async (config) => {
    const session = await getSession();
    if (session && !config.headers["Authorization"]) {
      config.headers["Authorization"] = `Bearer ${session.accessToken}`;
    }
    return config;
  });

  instance.interceptors.response.use(
    (response) => response,
    (error) => {
      // Handle error response
      console.error("Request failed", error);
      return Promise.reject(error);
    }
  );

  return instance;
};

export default getAxiosAuthClientInstance;

Try this solution

@lunarW1TCH
Copy link

If anyone stumbles upon it I solved it by fetching the session in main layout of my app and passing it to a component which sets it in a zustand store. I am not calling useSession anymore as it seems to be the culprit.

@john-subba
Copy link

If anyone stumbles upon it I solved it by fetching the session in main layout of my app and passing it to a component which sets it in a zustand store. I am not calling useSession anymore as it seems to be the culprit.

useSession with the sessionProvider is the culprit if u use getServerSession it doesnt give the issue
but the problem if to use update() function to update the session u need to use useSession hook no other way around it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Ask how to do something or how something works
Projects
None yet
Development

No branches or pull requests

10 participants