5/ NextAuth with GoogleProvider: sessions
Tags: nextauth, nextjs, googleprovider
Published: 2024-04-01 16:18:50

This is the second part on the basic configuration of `NextAuth` with `GoogleProvider`. The finished code for this chapter is available on [github (branch: basicgoogleprovider)](https://github.com/peterlidee/NNAS/tree/basicgoogleprovider).

## useSession in action

Let's add the `useSession` hook to our `<SingInButton />` since that is already a client component. We log the session:

```jsx
'use client';

import { signIn, useSession } from 'next-auth/react';

export default function SignInButton() {
  const { data: session, status, update } = useSession();
  console.log('session', session);
  return (
    <button
      className='bg-sky-400 rounded-md px-4 py-2'
      onClick={() => signIn()}
    >
      sign in
    </button>
  );
}
```

And in our browser console, we see this:

```
{
  "user": {
    "name": "Peter Jacxsens",
    "email": "email",
    "image": "imagelink"
  },
  "expires": "2024-04-06T16:03:44.887Z"
}
```

Where does this come from? This is the default `NextAuth` setup for `GoogleProvider`. When we do our login process, some `NextAuth` code had a chat with Google and got above user data. `NextAuth` then put that in a `JWT token` and wrote it into a cookie. `useSession` reads the cookie, gets the `JWT token`, extracts the data from it and returns it. And that is what we just logged into our browser.

Note that the session comes from our token in the cookie. `NextAuth` does not go to Google every time to get this info.

## getServerSession in action

What are we building here? When a user is **not** signed in, we want to display the sign in button. But when a user **is** signed in, we want to display the username and a sign out button.

![signed in with nextauth googleprovider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tciq44dg74l6er8zmcc0.png)

![signed out with nextauth googleprovider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djxrybofufsmbk0zhs5q.png)

First, go back to the `<SignInButton />` and remove the `useSession` hook and `console.log`:

```jsx
// frontend/src/app/components/header/SignInButton.tsx

'use client';

import { signIn } from 'next-auth/react';

export default function SignInButton() {
  return (
    <button
      className='bg-sky-400 rounded-md px-4 py-2'
      onClick={() => signIn()}
    >
      sign in
    </button>
  );
}
```

Duplicate this file, rename it to SignoutButton, import `signOut` from `NextAuth`:

```jsx
// frontend/src/app/components/header/SignOutButton.tsx

'use client';

import { signOut } from 'next-auth/react';

export default function SignOutButton() {
  return (
    <button
      className='bg-sky-400 rounded-md px-4 py-2'
      onClick={() => signOut()}
    >
      sign out
    </button>
  );
}
```

This should be straightforward, we made a sign out button and `NextAuth` provides us with a `signOut` function.

Create a new component `<NavbarUser />`. This will be an async server component that uses the `getServerSession` function.

```jsx
// frontend/src/app/components/header/NavbarUser.tsx

import { getServerSession } from 'next-auth';
import { authOptions } from '@/app/api/auth/[...nextauth]/authOptions';
import SignInButton from './SignInButton';
import SignOutButton from './SignOutButton';

export default async function NavbarUser() {
  const session = await getServerSession(authOptions);
  console.log('session', session);

  if (!session) {
    return <SignInButton />;
  }
  return (
    <>
      <div className='text-sky-700'>{session.user?.name}</div>
      <SignOutButton />
    </>
  );
}
```

Again, simple. We call our `getServerSession` function with the `authOptions` object. We log session and then use it to show either a logged in or logged out UI.

Finally, in our `<Navbar />` replace `<SignInButton />` with `<NavbarUser />` and let us take a look at session. As this is a server session, it will only log in the terminal, not in our browser:

```
getServerSession {
  "user": {
    "name": "Peter Jacxsens",
    "email": "email",
    "image": "imagelink"
  }
}
```

We get the user object as before but not an expires date. [There is a reason](https://next-auth.js.org/configuration/nextjs#in-app-router) for this but we will not get into that in this series.

## The auth flow

Testing time. We click sign out, the page does a full reload and then shows only the login button. Our terminal now shows:

```
getServerSession: null
```

We click the _sign in_ button, page does a full reload to the default sign in page (the ugly one). We click _sign in with Google_ button. This time google no longer asks us for permission but we are directly signed in and get redirect to our home page, again with a full page reload. Our terminal logs our user again.

And that's it. We have full sign in and out functionality and we know how to check if the user is logged in using the client component `useSession` hook or the server side `getServerSession` function.

## Client or server components

At this time, you may be wondering when to use `useSession` or `getServerSession` and that is pretty simple. We use the same rational `Next` uses. Always use server component except when you need a client component.

When do you need client components? When you need:

- Interactivity or event listeners (f.e. a button)
- Hooks
- Browser only api's like `localstorage` or `geolocation`
- Class components

## Expires

A `NextAuth` session has a limited lifespan of 30 days. When the session expires, you will have to login again. The session lifespan can be set in the `NextAuth` settings. Both `NextAuth` and `Strapi` recommend a max of 30 days for `JWT tokens`.

## Some extra components

We're going to do some cleanup. Firstly, remove the `console.log` from our `<NavbarUser />` component. Next, we are going to add 2 components, one with `useSession` and one with `getServerSession`.

We are going to use these 2 components to:

1. Make a clear visual of the logged in state.
2. To have easy access to the session by logging it out from these components.
3. To handle some server and client component issues that we will face later on.

```tsx
// frontend/src/components/loggedIn/LoggedInClient.tsx

'use client';

import { useSession } from 'next-auth/react';

export default function LoggedInClient() {
  const { data: session } = useSession();
  console.log('useSession', session);
  return (
    <div
      className={`p-4 basis-2/4 rounded-sm text-center ${
        session ? 'bg-green-400' : 'bg-red-400'
      }`}
    >
      Client:{' '}
      {session ? `logged in as ${session.user?.name}.` : 'not logged in.'}
    </div>
  );
}
```

and

```tsx
// frontend/src/components/loggedIn/LoggedInServer.tsx

import { authOptions } from '@/app/api/auth/[...nextauth]/authOptions';
import { getServerSession } from 'next-auth';

export default async function LoggedInServer() {
  const session = await getServerSession(authOptions);
  console.log('getServerSession', session);
  return (
    <div
      className={`p-4 basis-2/4 rounded-sm text-center ${
        session ? 'bg-green-400' : 'bg-red-400'
      }`}
    >
      Server:{' '}
      {session ? `logged in as ${session.user?.name}.` : 'not logged in.'}
    </div>
  );
}
```

Add these components into the root `layout` and this is what we get: (obviously green when logged in)

![logged in with nextauth googleprovider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1b10k9fkjt5gtwq1s0q9.png)

## Summary

We configured `GoogleProvider` in `NextAuth`. We added a _sign in_ button. This leads us to a default `NextAuth` page that is not really usable in real live but does let us sign in with Google.

The `useSession` hook and `getServerSession` function let us verify if there is a user. When logged in, they return a user object with a name, email and image property. When logged out they return null. We use this info and change our UI accordingly.

But there are some issues:

1. We really need a custom sign in page. Also, what's with all of the reloads?
2. We haven't done any integration with `Strapi`. It has all been frontend. Currently no user will ever end up in our DB.

We will tackle these issues in the next chapters.

As a closure, I would like to mention that a lot of the information in this chapter came from this [youtube video by Sakura Dev](https://www.youtube.com/watch?v=A53T9_V8aFk) and this [youtube video by Jack Herrington](https://www.youtube.com/watch?v=md65iBX5Gxg). But be careful, it is not 100% the same. So don't just drop snippets from one into the other! This goes for all tutorials. There is no one and only correct way to use `Nextauth`.

---

If you want to support my writing, you can [donate with paypal](https://www.paypal.com/donate/?hosted_button_id=4D78YQU4V5NEJ).