# Reading "Getting Started with NextAuth.js"

These are my comments when reading the Getting Started (opens new window) guide of NextAuth.js for a Nextra lab.

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

In New Project (opens new window) the guide suggests to clone the repo https://next-auth-example.vercel.app/ (opens new window) and learn from it, so I cloned it.

In the main branch the version of next-auth is beta and next is latest. The example used the app folder instead of pages. The version of next installed at this time (November 2024) was:

I noticed the next-auth has no public documentation for the beta version.

There are 5 branches. The others 4 are stale. 2 test/* branches, one feat/* branch and one apple-sign-in branch using next 12. All of them can be used to learn.

Conclusion

Discarded the idea of using it as the main learning resource.

So, I follow with the section Existing Project (opens new window) path.

# Initial Steps

I started fron the nextra assignment for the fake student https://github.com/ULL-MII-SYTWS-2425/nextra-casiano-rodriguez-leon-alu0100291865 (opens new window).

Made a new branch guide from commit 526ce78 (opens new window) when I was on main: https://github.com/ULL-MII-SYTWS-2425/nextra-casiano-rodriguez-leon-alu0100291865/tree/guide (opens new window)

Added the API route pages/api/auth/[...nextauth].js as explained at https://next-auth.js.org/getting-started/example#add-api-route (opens new window). See https://github.com/ULL-MII-SYTWS-2425/nextra-casiano-rodriguez-leon-alu0100291865/blob/guide/pages/api/auth/[...nextauth].js (opens new window)

Bug

I forced the script "dev": "next -p 3000", to listen in port 3000 in the package.json, since I have found a bug in next-auth GitHub provider. The sigin page seems to have hardcoded the port to 3000 http://localhost:3000/api/auth/signin/github: https://github.com/ULL-MII-SYTWS-2425/nextra-casiano-rodriguez-leon-alu0100291865/blob/guide/package.json#L6-L10 (opens new window)

# Add API route

When reading the section [Add API route](Add API route) for Nextra I've got errors that were fixed by changing the calls to GithubProvider and NextAuth by adding .default:

File pages/api/auth/[...nextauth].js







 







 

import NextAuth from "next-auth" // https://next-auth.js.org/getting-started/example#add-api-route
import GithubProvider from "next-auth/providers/github"

export const authOptions = {
  // Configure one or more authentication providers
  providers: [
    GithubProvider.default({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    // ...add more providers here
  ]
}

export default NextAuth.default(authOptions)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

For an explanation of how Next.js API routes work see https://ull-pl.vercel.app/nextra-playground/authorization/next-auth-tutorial#creating-the-server-config (opens new window) at my PL Notes.

Behind the scenes, this code creates all the relevant OAuth API routes within /api/auth/* so that auth API requests can be handled by NextAuth.js. In this way, NextAuth.js stays in charge of the whole application's request/response flow. See https://ull-pl.vercel.app/nextra-playground/authorization/next-auth-tutorial#routes (opens new window)

# SessionProvider component in pages/_app.jsx

I also changed the main file pages/_app.jsx to use the SessionProvider as explained at https://next-auth.js.org/getting-started/example#configure-shared-session-state (opens new window)

File pages/_app.jsx:






 



 


 

 



/* Old code
export default function App({ Component, pageProps }) {
  return <Component {...pageProps} />
}
*/
import { SessionProvider } from "next-auth/react"

export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

See https://github.com/ULL-MII-SYTWS-2425/nextra-casiano-rodriguez-leon-alu0100291865/blob/guide/pages/_app.jsx (opens new window)

# login-btn component

Added the login-btn component as explained at https://next-auth.js.org/getting-started/example#frontend---add-react-hook (opens new window)

import { useSession, signIn, signOut } from "next-auth/react"

export default function Component() {
  const { data: session, status: status } = useSession()
  if (status === "loading") {
    return <p>Loading...</p>
  }
  if (session) {
    return (
      <>
        Signed in as {session.user.email} <br />
        <button onClick={() => signOut()}>Sign out</button>
      </>
    )
  }
  return (
    <>
      Not signed in <br />
      <button onClick={() => signIn()}>Sign in</button>
    </>
  )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# useSession() NextAuth React Hook

The useSession() (opens new window) React Hook in the NextAuth.js client is the easiest way to check if someone is signed in.

useSession() returns an object containing two values: data and status:

data: This can be three values: Session / undefined / null.

  • when the session hasn't been fetched yet, data will be undefined
  • in case it failed to retrieve the session, data will be null
  • in case of success, data will be a Session object.

status: Is a enum mapping to three possible session states: "loading" | "authenticated" | "unauthenticated"

To wrap all the pages, make sure that <SessionProvider> is added to pages/_app.js.

See https://github.com/ULL-MII-SYTWS-2425/nextra-casiano-rodriguez-leon-alu0100291865/blob/guide/components/login-btn.jsx (opens new window)

# signIn() method

Using the client side signIn() (opens new window) method ensures the user ends back on the page they started on after completing a sign in flow. It will also handle CSRF Tokens for you automatically when signing in with email.

By default, when calling the signIn() method with no arguments, you will be redirected to the NextAuth.js sign-in page. If you want to skip that and get redirected to your provider's page immediately, call the signIn() method with the provider's id.

For example to sign in with GitHub:

import { signIn } from "next-auth/react"

export default () => (
  <button onClick={() => signIn("github")}>Sign in with GitHub</button>
)
1
2
3
4
5

The signIn() method receives a second argument, an object with options. The most common options are callbackUrl (opens new window) and redirect (opens new window).

The callbackUrl specifies to which URL the user will be redirected after signing in. Defaults to the page URL the sign-in is initiated from.

Examples:

signIn(undefined, { callbackUrl: '/foo' }) // A relative url starting with a slash
signIn('google', { callbackUrl: 'http://localhost:3000/bar' }) // Or an absolute URL at the same host name,
signIn('email', { email, callbackUrl: 'http://localhost:3000/foo' })
signIn('credentials', { redirect: false, password: 'password' })   // Disable the redirect and handle the error on the same page.
signIn('email', { redirect: false, email: 'bill@fillmurray.com' }) // In such case signIn will return a Promise,
1
2
3
4
5

If redirect is set to false, the signIn method will return a Promise that resolves to an object with the following properties:

{
  error: string | undefined // Error message if there was an error
  status: number // HTTP status code
  ok: boolean // `true` if the request was successful, `false` otherwise
  url: string | null // The URL the user should be redirected to or null `null` if there was an error
}
1
2
3
4
5
6
Last Updated: 12 days ago