---
title: Authenticating
description: Learn about authentication patterns in Next.js apps and explore a few examples.
---

Authentication verifies who a user is, while authorization controls what a user can access. Next.js supports multiple authentication patterns, each designed for different use cases. This page will go through each case so that you can choose based on your constraints.

## Authentication Patterns

The first step to identifying which authentication pattern you need is understanding the [data-fetching strategy](/docs/pages/building-your-application/data-fetching) you want. We can then determine which authentication providers support this strategy. There are two main patterns:

- Use [static generation](/docs/pages/building-your-application/rendering/static-site-generation) to server-render a loading state, followed by fetching user data client-side.
- Fetch user data [server-side](/docs/pages/building-your-application/rendering/server-side-rendering) to eliminate a flash of unauthenticated content.

### Authenticating Statically Generated Pages

Next.js automatically determines that a page is static if there are no blocking data requirements. This means the absence of [`getServerSideProps`](/docs/pages/building-your-application/data-fetching/get-server-side-props) and `getInitialProps` in the page. Instead, your page can render a loading state from the server, followed by fetching the user client-side.

One advantage of this pattern is it allows pages to be served from a global CDN and preloaded using [`next/link`](/docs/pages/api-reference/components/link). In practice, this results in a faster TTI ([Time to Interactive](https://web.dev/interactive/)).

Let's look at an example for a profile page. This will initially render a loading skeleton. Once the request for a user has finished, it will show the user's name:

```jsx filename="pages/profile.js"
import useUser from '../lib/useUser'
import Layout from '../components/Layout'

const Profile = () => {
  // Fetch the user client-side
  const { user } = useUser({ redirectTo: '/login' })

  // Server-render loading state
  if (!user || user.isLoggedIn === false) {
    return <Layout>Loading...</Layout>
  }

  // Once the user request finishes, show the user
  return (
    <Layout>
      <h1>Your Profile</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile
```

You can view this [example in action](https://iron-session-example.vercel.app/). Check out the [`with-iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) example to see how it works.

### Authenticating Server-Rendered Pages

If you export an `async` function called [`getServerSideProps`](/docs/pages/building-your-application/data-fetching/get-server-side-props) from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`.

```jsx
export async function getServerSideProps(context) {
  return {
    props: {}, // Will be passed to the page component as props
  }
}
```

Let's transform the profile example to use [server-side rendering](/docs/pages/building-your-application/rendering/server-side-rendering). If there's a session, return `user` as a prop to the `Profile` component in the page. Notice there is not a loading skeleton in [this example](https://iron-session-example.vercel.app/).

```jsx filename="pages/profile.js"
import withSession from '../lib/session'
import Layout from '../components/Layout'

export const getServerSideProps = withSession(async function ({ req, res }) {
  const { user } = req.session

  if (!user) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    }
  }

  return {
    props: { user },
  }
})

const Profile = ({ user }) => {
  // Show the user. No loading state is required
  return (
    <Layout>
      <h1>Your Profile</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile
```

An advantage of this pattern is preventing a flash of unauthenticated content before redirecting. It's important to note fetching user data in `getServerSideProps` will block rendering until the request to your authentication provider resolves. To prevent creating a bottleneck and increasing your TTFB ([Time to First Byte](https://web.dev/time-to-first-byte/)), you should ensure your authentication lookup is fast. Otherwise, consider [static generation](#authenticating-statically-generated-pages).

## Authentication Providers

Now that we've discussed authentication patterns, let's look at specific providers and explore how they're used with Next.js.

### Bring Your Own Database

<details open>
  <summary>Examples</summary>

- [with-iron-session](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session)
- [next-auth-example](https://github.com/nextauthjs/next-auth-example)

</details>

If you have an existing database with user data, you'll likely want to utilize an open-source solution that's provider agnostic.

- If you want a low-level, encrypted, and stateless session utility use [`iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session).
- If you want a full-featured authentication system with built-in providers (Google, Facebook, GitHub…), JWT, JWE, email/password, magic links and more… use [`next-auth`](https://github.com/nextauthjs/next-auth-example).

Both of these libraries support either authentication pattern. If you're interested in [Passport](http://www.passportjs.org/), we also have examples for it using secure and encrypted cookies:

- [with-passport](https://github.com/vercel/next.js/tree/canary/examples/with-passport)
- [with-passport-and-next-connect](https://github.com/vercel/next.js/tree/canary/examples/with-passport-and-next-connect)

### Other Providers

To see examples with other authentication providers, check out the [examples folder](https://github.com/vercel/next.js/tree/canary/examples).

<details open>
  <summary>Examples</summary>

- [Auth0](https://github.com/vercel/next.js/tree/canary/examples/auth0)
- [Clerk](https://github.com/vercel/next.js/tree/canary/examples/with-clerk)
- [Firebase](https://github.com/vercel/next.js/tree/canary/examples/with-firebase-authentication)
- [Magic](https://github.com/vercel/next.js/tree/canary/examples/with-magic)
- [Nhost](https://github.com/vercel/next.js/tree/canary/examples/with-nhost-auth-realtime-graphql)
- [Ory](https://github.com/vercel/examples/tree/main/solutions/auth-with-ory)
- [Supabase](https://github.com/vercel/next.js/tree/canary/examples/with-supabase)
- [Supertokens](https://github.com/vercel/next.js/tree/canary/examples/with-supertokens)
- [Userbase](https://github.com/vercel/next.js/tree/canary/examples/with-userbase)

</details>
