Understand NextAuth.js flow

What happens when a user clicks "Log in"?

NextAuth.js can be used either with or without a database. In this article, we will explain the case where no database is involved. Once you have a good understanding of the mechanism behind NextAuth.js, plugging in a database will not be much different.

What happens when a user logs in

log-in flow diagram


  • There are 3 parties involved:
    1. Browser, a.k.a. a user, a.k.a. a client-side of Next.js
    2. Serverless, a.k.a. a server-side of Next.js
    3. Auth0, an OAuth provider
  • Our Next.js code runs on 1. and 2.. So these 2 parties are our website. We can fully control both.
  • On the other hand, 3. can be any OAuth provider, such as GitHub or Google. This is an external website that we need to cooperate.

Step-by-step explanation:

  1. A user (browser) clicks "Log in". The browser will make a request to our Next.js serverless. The URL destination depends on the OAuth provider, e.g. api/auth/signin/auth0.
  2. The serverless responds with a redirect status code.
  3. The browser then follows the redirection, navigate away from our website, and land on Auth0 website.
  4. The user (who is using the browser) is asked to log in to Auth0. If success, Auth0 will respond with another redirection and also attach an access code for using in the next step. Moreover, Auth0 also set cookies to remember a session between the browser and Auth0. Note that this is not the session between the browser and the serverless.
  5. The browser follows the redirection and navigate back to our website. The destination URL is something like api/auth/callback/auth0?code=123. It is sending the access code to the serverless.
  6. The serverless does not immediately send a response back yet. It instead makes a request to Auth0, giving the access code in exchange for an access token.
  7. Auth0 responds with the access token to the serverless.
  8. After receiving the access token from Auth0, the serverless then sends a response back to the browser, set cookies, and remember the session between the browser and the serverless. Now the user is logged in successfully.

What happens when the page calls API routes (after the user has logged in)

calling api flow diagram


  • NextAuth's useSession() runs on the Next.js client-side (browser)
  • NextAuth's getServerSession() runs on the Next.js server-side (serverless)
  • If our website need to call an external API endpoint, e.g. https://external-domain.com/api, we may need to proxy it through our API routes (serverless). So, it would be:
    🡣 (cookies)
    Serverless, e.g. my-domain.com/api/proxy 
    Get an access token on the server side
    🡣 (access token)