# Clerk Blog — Page 9

# How We Roll – Chapter 7: JWT Single Sign-On
URL: https://clerk.com/blog/how-we-roll-jwt-sso.md
Date: 2023-07-14
Category: Company
Description: How We Roll is a deep dive into how Clerk implements authentication. This chapter covers how Clerk integrates with BaaS providers with JWT SSO.

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, roll) authentication at Clerk.

## Chapter 7: JWT Single Sign-On

Clerk offers [seamless integration](/docs/integration/overview) with Backend as a Service (BaaS) providers like [Firebase](https://firebase.google.com), [Supabase](https://supabase.com), and [Convex](https://www.convex.dev). BaaS providers enable developers to build applications quickly without worrying about the backend and infrastructure, similar to what Clerk does for auth. These providers abstract complex infrastructure logic and make it accessible to the front-end client through simple APIs and SDKs.

With that being said, any time you are accessing data from the client, there is a security concern; proper authentication and authorization is paramount, which is why these providers enable developers to configure security rules.

![How We Roll Jwt Sso guide illustration](./14852af290484142fa8bcd2f2d9db1925a8261cc-1346x344.png)

Clerk's officially supported integrations with these providers allow developers to seamlessly leverage Clerk for authentication in applications that depend on a BaaS. This is achieved through a concept called **JWT Single Sign-On**.

### Web APIs love JWTs

A JSON Web Token (JWT, pronounced *jot*) is a JSON string that is cryptographically signed and base64 encoded. Anyone can decode and read this key, but it can only be generated and verified using a secret key (or a private-public key pair). It’s like a passport that web apps create to give users access.

Claims are the credentials encoded in a JWT that are used to decide what resources the user has access to. If a JWT is a passport, claims are the contents of the passport, including your name, date of birth, passport number, and any stamps.

To learn more about JWTs, check out [this blog post](/blog/guide-JWT-authentication-JSON-Web-Tokens). Or implement JWT auth from scratch with [this blog post](/blog/adding-jwt-authentication-to-react).

### JWT Single Sign-On

JWT SSO is conceptually similar to OIDC or SAML Single Sign-On - it enables multiple services to use a single identity provider.

**SAML refresher:** Security Assertion Markup Language is an XML-based protocol that enables Single Sign-On, similar
to OIDC. SAML is used heavily in enterprise environments with a central auth system that issues XML tokens to
applications when a user needs to authenticate.

OIDC and SAML providers act as a source of identity for a user. They provide information about the user, like email address, name, avatar, and roles.

JWT SSO providers essentially share the logged-in session of the user with the services. They provide a token that represents not just the user, but the fact that the user *recently* signed in. If these tokens are short-lived, they can be regenerated, as long as the user is still logged in. JWT SSO allows the user to “be logged in” to multiple services (for example Clerk and Supabase) at the same time.

Clerk achieves this by generating a custom JWT for the signed-in user, which can then be used to make API requests to the provider. Developers can configure **JWT templates** in the Clerk Dashboard to generate these custom tokens.

```tsx
try {
  const token = await Clerk.session.getToken({ template: 'template_name' })
  // use token to call external service
} catch (e) {
  // handle error
}
```

### JWT Templates

To generate custom JWTs on the client, developers can configure a JWT template in the Clerk Dashboard. The template provides all the configurations necessary for JWT SSO to work with various providers.

These are some of the configuration options for JWT templates available on the Clerk Dashboard.

#### Token lifetime

Based on caching or security policies, developers can configure how long the token should be valid for. A long-lived token can be generated once, cached, and reused. A short-lived token has to be generated every time a request is made.

#### Custom signing key

Different providers have different ways to validate a JWT that they did not generate. For example, Firebase and Supabase require the tokens to be generated using their own secret. Developers can get this secret from the provider's dashboard, and configure the JWT template to use this secret key in the Clerk Dashboard.

When this token is generated and sent to the provider, the provider will be able to validate the token since it was generated using their key.

#### Issuer defined key

Other providers like Convex do not require using their own secrets. Instead, they can be configured with a public key or with **JSON Web Key Set** (JWKS).

A **JSON Web Key** is a public key that can be used to validate a token but cannot be used to generate one. An auth provider (issuer) like Clerk exposes its JSON Web Keys in the JWKS endpoint, which can be used by external providers to verify if a JWT was generated by Clerk. Similar to the JWT secret, the JWKS is unique to each application on Clerk.

Services like Convex allow developers to define an Issuer and a JWKS endpoint, which tells the service where to find the JWKS to validate the tokens. Both the Issuer URL and JWKS URL are available on the JWT Template configuration page on the Clerk DashboardTemplate page.

#### Custom Claims

Along with validating that the token was securely generated, data providers also need to know who the user is to check against security rules.

Most providers expect specific claims in the JWTs, optionally within a namespace. Clerk has pre-built JWT templates for popular services, and the templates are already configured with custom claims that the specific services look for. Within custom claims, handlebars-style templating can be used to include user information with shortcodes.

```json {{ title: 'JWT Template Custom Claims with Shortcodes' }}
{
  "aud": "convex",
  "name": "{{user.full_name}}",
  "nickname": "{{user.username}}",
  "picture": "{{user.image_url}}",
  "given_name": "{{user.first_name}}",
  "family_name": "{{user.last_name}}",
  "email": "{{user.primary_email_address}}",
  "phone_number": "{{user.primary_phone_number}}",
  "email_verified": "{{user.email_verified}}",
  "phone_number_verified": "{{user.phone_number_verified}}",
  "updated_at": "{{user.updated_at}}"
}
```

## Summary

Clerk strives to be a complete auth solution with an exceptional developer experience, and integrating with BaaS providers is an important part. Clerk’s JWT Single Sign-On enables this through session-sharing, or sharing the logged in state of the user with the BaaS providers, so developers can focus on building applications with minimal glue code or configuration required.

To learn more about the integrations supported by JWT SSO, check out our [Integration docs](/docs/integration/overview).

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- [How We Roll – Chapter 10: Roundup](/blog/how-we-roll-roundup)

---

# Migrating from Pages Router to App Router: An Incremental Guide
URL: https://clerk.com/blog/migrating-pages-router-to-app-router-an-incremental-guide.md
Date: 2023-07-03
Category: Guides
Description: Already know the /pages directory? Here's a simple way to migrate to the /app directory in Next.js 13.

The Next.js [App Router](https://nextjs.org/docs/app) (in the **/app** directory) is a new way to build React applications. If you're already familiar with the [Pages Router](https://nextjs.org/docs/pages) (in the **/pages** directory), Next.js has made it really easy to adopt the App Router incrementally, quite literally on a page-by-page basis. This guide explains how.

## How is this guide different?

The App Router already has a [migration guide](https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration), so how is this different?

We want to demonstrate a 1-to-1 mapping of Pages Router to App Router, but this is not a complete migration. In the snippets below you will see obvious potential refactors, and **that is on purpose.**

As an example, one App Router snippet below still has function called `getServerSideProps`. It doesn't make sense to keep that name, but we want to demonstrate how `getServerSideProps` can be expressed in the context of the App Router.

One more disclaimer: this will not explain how to migrate *everything*. We focused on the best practices for the Pages Router in Next.js 12.3, but left out older APIs like `getInitialProps`.

## One quick clarification

You probably know that the App Router supports both **Client Components** and the newly introduced **Server Components**.

Before the App Router, Client Components were just called Components. We want to clarify that after the App Router, **absolutely nothing has changed about them.**

Most importantly, within the App Router, **Client Components** are still rendered on the server, then hydrated on client. Search engine crawlers can still index their HTML.

Within this guide, the React code from your Pages Router will be copied to new files and labeled with `"use client"` at the top. This is expected, since we're doing a 1-to-1 mapping.

## Migrating from the Pages Router to the App Router

### 0. Create the /app directory

Before you can get started with the App Router, you will first need to create a **/app** directory as a sibling to your **/pages** directory.

### 1. Migrate /pages/\_document to the App Router

If you have a [Custom Document](https://nextjs.org/docs/pages/building-your-application/routing/custom-document) at **/pages/\_document.tsx**, it should look something like this, though likely with some customization:

```tsx {{ title: '/pages/_document.tsx' }}
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}
```

We need to convert this into a [Root Layout](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#root-layout-required), which can be treated as a 1-to-1 corollary to a Custom Document:

1. Clone **/pages/\_document.tsx** into **/app/layout.tsx**. We will keep both files since we're doing incremental adoption. (If you use .jsx that is no problem, you can use layout.jsx instead)
2. Remove the **next/document** import line entirely
3. Replace `<Html>` and `</Html>` with the lowercase, HTML equivalent `<html>` and `</html>`. For accessibility, it's best to add a language to your opening tag, like `<html lang="en">`
4. Replace `<Head>` and `</Head>` with the lowercase, HTML equivalent `<head>` and `</head>`. If you only have a self-closing `<Head />`, you can remove it entirely
5. Replace `<Main />` with `{children}`, and update the default function export to accept a `{children}` argument. For Typescript users, `children` is of type `React.ReactNode`
6. Remove `<NextScript />` entirely

When complete, **/app/layout.tsx** should look more like this, plus your customizations:

```tsx {{ title: '/app/layout.tsx' }}
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
```

**Important: /app/layout.tsx is required** in the **/app** directory. If you do not have a Custom Document, you can copy-paste the above sample directly into **/app/layout.tsx**.

### 2. Migrate /pages/\_app.tsx to the App Router

**Note:** If you do not have a file at **/pages/\_app.tsx** you can skip to Step 3.

If you have a [Custom App](https://nextjs.org/docs/pages/building-your-application/routing/custom-app) at **/pages/\_app.tsx**, it should look something like this, though likely with some customization:

```tsx {{ title: '/pages/_app.tsx' }}
import type { AppProps } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
```

The **/app** directory does not have a 1-to-1 corollary for a Custom App, but it can easily be expressed in the new structure:

1. Clone **/pages/\_app.tsx** into **/app/ClientLayout.tsx**. We will keep both files since we're doing incremental adoption. (If you use .jsx that is no problem, you can use ClientLayout.jsx instead)
2. Add a new line to the top of the file that reads `"use client"` (with the quotes)
3. Replace the default export's function signature. Instead of taking `Component` and `pageProps` arguments, it should only take a `children` argument. For Typescript users, `children` is of type `React.ReactNode`.
4. Replace `<Component {...pageProps} />` with `<>{children}</>`, or just `{children}` if you have another wrapping element
5. If there are any remaining references to `pageProps`, please comment them out for now, and revisit them on a page-by-page basis. Next.js has added a new [metadata API](https://nextjs.org/docs/app/building-your-application/optimizing/metadata) that should normally be used in place of accessing `pageProps` here
6. We recommend changing the default export name from `MyApp` to `ClientLayout`. It is not strictly necessary, but it is more conventional

When complete, **/app/ClientLayout.tsx** should look more like this, plus your customizations:

```tsx {{ title: '/app/ClientLayout.tsx' }}
'use client'

export default function ClientLayout({ children }: { children: React.ReactNode }) {
  return <>{children}</>
}
```

Now, this is where things get a little different:

- In the Pages Router, **/pages/\_app.tsx** is a "magic" layout file that is automatically added to the React tree
- In the App Router, the only layout file automatically added to the React tree is the Root Layout from Step 1. So, we will need to manually import and mount our `ClientLayout` inside **/app/layout.tsx**

Open **/app/layout.tsx**, import ClientLayout, and use it to wrap `{children}`. When complete, your Root Layout should look like this, plus any customizations from Step 1:

```tsx {{ title: '/app/layout.tsx' }}
import ClientLayout from './ClientLayout'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ClientLayout>{children}</ClientLayout>
      </body>
    </html>
  )
}
```

### 3. Migrate each page to the App Router

Now that your layout has been copied into the App Router, it's time to start migrating your pages one-by-one. There will be a few steps for each page:

1. Create a directory for the page
2. Create one file to handle data fetching
3. Create one file to render the page
4. Remove the Pages Router page

For the avoidance of doubt: yes, we will be splitting your Pages Router page into two files: one for data fetching and one for rendering.

#### 3.1. Create a directory for the page

Both the Pages Router and the App Router are "filesystem routers," but they are organized slightly differently. In the App Router, each page gets its own directory. Here is how to determine the directory name:

- If your file is named **index.tsx**, create the same parent directory structure
  - For **/pages/foo/index.tsx**, create **/app/foo**
  - For **/pages/index.tsx**, you already have **/app**
- If your file is **not** named **index.tsx**, create a directory with that filename
  - For **/pages/bar.tsx**, create **/app/bar**
  - For **/pages/baz/\[slug].tsx**, create **/app/baz/\[slug]**
  - For **/pages/baz/\[\[...slug].tsx**, create **/app/baz/\[\[...slug]]**

#### 3.2. Create a file to handle data fetching

Inside your page directory, create a file called **page.tsx** to handle data fetching. Copy-paste the following snippet as the foundation of this file (**Note:** we will create **ClientPage.tsx** in 3.3.):

```tsx {{ title: 'page.tsx' }}
import ClientPage from './ClientPage'

export default async function Page() {
  return <ClientPage />
}
```

If your Pages Router file does not have any data fetching, you can continue on to the next step. Otherwise, find your data fetcher below to learn how it can be migrated:

**Migrating getStaticProps to the App Router**

Consider the following is your implementation of `getStaticProps`:

```typescript
export const getStaticProps: GetStaticProps<PageProps> = async () => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}
```

To migrate this with as little modification as possible, we will:

1. Copy-paste `getStaticProps` into **page.tsx**
2. Call `getStaticProps` from within our `Page` component
3. Add `export const dynamic = "force-static"` so the page data is fetched once and cached, not refetched on every load
4. Pass the result to our (not yet created) `ClientPage` component

Here is the end result:

```tsx {{ title: 'page.tsx' }}
import ClientPage from './ClientPage'

export const getStaticProps: GetStaticProps<PageProps> = async () => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}

export const dynamic = 'force-static'

export default async function Page() {
  const { props } = await getStaticProps()
  return <ClientPage {...props} />
}
```

**Migrating getServerSideProps to the App Router**

Consider the following implementation of `getServerSideProps`:

```typescript
import { getAuth } from '@clerk/nextjs/server'

export const getServerSideProps: GetServerSideProps<PageProps> = async ({ req }) => {
  const { userId } = getAuth(req)

  const res = await fetch('https://api.example.com/foo', {
    headers: {
      Authorization: `Bearer: ${process.env.API_KEY}`,
    },
  })
  const data = await res.json()
  return { props: { data } }
}
```

To migrate this with as little modification as possible, we will:

1. Copy-paste `getServerSideProps` into **page.tsx**
2. Add `export const dynamic = "force-dynamic"` so the page data is refetched on every load
3. Replace any usage of `req` with the App Router equivalent
4. Our example uses [Clerk for authentication](/nextjs-authentication), so the end result will replace this line with its App Router-compatible replacement
5. Replace `req.headers` with the new [headers() helper](https://nextjs.org/docs/app/api-reference/functions/headers)
6. Replace `req.cookies` with the new [cookies() helper](https://nextjs.org/docs/app/api-reference/functions/headers)
7. Replace `req.url.searchParams` with the new [searchParams helper](https://nextjs.org/docs/app/api-reference/file-conventions/page#searchparams-optional)
8. Replace any Dynamic Route segment usage with the new [params helper](https://nextjs.org/docs/app/api-reference/file-conventions/page#params-optional)
9. Call `getServerSideProps` from within our `Page` component
10. Pass the result to our (not yet created) `ClientPage` component

Here is the end result:

```tsx {{ title: 'page.tsx' }}
import { auth } from '@clerk/nextjs'
import ClientPage from './ClientPage'

export const getServerSideProps: GetServerSideProps<PageProps> = async () => {
  const { userId } = auth()

  const res = await fetch('https://api.example.com/foo', {
    headers: {
      Authorization: `Bearer: ${process.env.API_KEY}`,
    },
  })
  const data = await res.json()
  return { props: { data } }
}

export const dynamic = 'force-dynamic'

export default async function Page() {
  const { props } = await getServerSideProps()
  return <ClientPage {...props} />
}
```

**Migrating getStaticPaths to the App Router**

Consider the following implementation of `getStaticPaths`:

```typescript
export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
  }
}
```

In the App Router, this implementation barely changes. It's simply given a new name (`generateStaticParams`) and the output is transformed to something simpler. That means you can use your old implementation directly, and simply transform the output.

Here is the end result – we included an example of how it can be used in tandem with `getStaticProps`:

```tsx {{ title: 'page.tsx' }}
import ClientPage from './ClientPage'

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
  }
}

export async function generateStaticParams() {
  const staticPaths = await getStaticPaths()
  return staticPaths.paths.map((x) => x.params)
}

export const getStaticProps: GetStaticProps<PageProps> = async ({ params }) => {
  const res = await fetch(`https://api.example.com/foo/${params.id}`)
  const data = await res.json()
  return { props: { data } }
}

export default async function Page({ params }) {
  const { props } = await getStaticProps({ params })
  return <ClientPage {...props} />
}
```

#### 3.3. Create a file to render the page

Now that data fetching is ready, we need to configure the rendering. To accomplish this:

- Copy your original Pages Router page into **ClientPage.tsx**
- Remove any data fetching code, since it now lives in **page.tsx**

That's it! We have already configured **page.tsx** to mount this file and pass props, so it should be working.

#### 3.4. Remove the Pages Router page

Now that your page is ready in the App Router, you can delete the old Pages Router variant.

## What's next?

Now that your Pages Router application is working in the App Router, it's time to start taking advantage of the App Router and React Server Components.

In particular, right now your **ClientPage.tsx** files are one big Client Component. Going forward, it's best to refactor this so `"use client"` is used as sparingly as possible, ideally only on small components. A big Server Component importing many small Client Components will lead to less Javascript sent to the client, and a faster experience for your end user.

---

# Social SSO in Next.js
URL: https://clerk.com/blog/social-sso-in-next-js.md
Date: 2023-06-24
Category: Guides
Description: In this article, we explore how to incorporate OAuth SSO into a Next.js project with JSON Web Tokens (JWTs) and the new app router from Next.js.

Authentication has always been a critical aspect of web development, with user data security being paramount.

As the digital world continues to evolve, so does the need for more efficient and secure authentication methods. However, users do not necessarily want to remember secure logins for every app they use.

This is where OAuth Single Sign-On (SSO) comes into play. OAuth simplifies the user authentication process by allowing users to log in with accounts they already have with other services like [Google](/blog/nextjs-google-authentication), Facebook, or Microsoft.

In this article, we will explore how to incorporate OAuth SSO into a Next.js project with [JSON Web Tokens (JWTs)](https://jwt.io/introduction) and Next.js’s new app router, and later see how Clerk, an [authentication service](/nextjs-authentication), can help simplify this and make it more secure. We will focus on GitHub SSO for simplicity, but most other OAuth providers can be implemented similarly.

Before we get started, if you ever need to look at the full source, code, the [example code is on GitHub](https://github.com/AsyncBanana/nextjs-sso).

## Set up the project

Before we start, make sure you are on Node v18+. You can check this by running `node -v` in a terminal.

### Scaffolding

We will use [create-next-app](https://nextjs.org/docs/getting-started/installation) to scaffold our project. First, you will want to open a terminal in the directory you want to put the project in and run:

```sh
npx create-next-app@latest
```

If you want to use a different package manager, use their own counterpart to `npx`, like `pnpx`. c`reate-next-app` will ask you some questions about your project. Name the project whatever you want; it doesn’t matter. For TypeScript, ESLint, Tailwind, and using `/src`, select no. For the app router, select yes. Finally, leave the import aliases unmodified. After, the output should look like this:

![Social Sso In Next Js guide illustration](./3831e3d2719600d436fc5a7f55c3528434e9b6e0-2000x1250.png)

Now, open that directory in a code editor of your choice. You will need to install jsonwebtoken, which we will use for verifying JWTs.

```sh
npm i jsonwebtoken
```

### Create a GitHub OAuth App

Next, we will need to create the OAuth app in GitHub. Go to [github.com/settings/applications/new](https://github.com/settings/applications/new) and fill out the information. Set the homepage URL to `http://localhost:3000` and the callback URL to `http://localhost:3000/callback` (if you are running the Next.js server on a port other than 3000, you can replace 3000 with that port). You can leave device flow unchecked. Click register and you will be sent to the new application page.

![Social Sso In Next Js guide illustration](./387ca25acbfc80693dda994683b9ed4a0ba430ae-2000x1250.png)

Now, let’s go back to the code for a minute. Create a new file called `.env.local`. This is where you will store your environment variables, which are variables that specify service keys or other configuration that is specific to each deployment and are specified by writing `VARIABLE_NAME=variable_value`, with each variable being on one line.

In the `.env.local` file, create a variable named `NEXT_PUBLIC_GITHUB_OAUTH_ID`. This will contain your GitHub OAuth application’s id. Note that the `NEXT_PUBLIC` prefix tells Next.js to allow the env variable to be accessed by replacing all calls to `process.env.NEXT_PUBLIC_GITHUB_OAUTH_ID` with the value of the variable at build time. If you did not include this prefix, only the server would be able to access the value, which is good for secrets. With that aside, we need to get the GitHub OAuth application id, which you can find on the application dashboard you were sent to earlier. Copy it and paste it into the .env file.

We also need to get a secret, which we will put with the variable `GITHUB_OAUTH_SECRET`. On the dashboard, you can click “Generate a client secret” to get a new secret. Copy it and paste it in the .env file under the new variable.

Finally, we need `JWT_SECRET`, which should be a random password we use for encrypting JWTs. You can use a [password generator](https://passwordsgenerator.net) for this.

That is it for set up! Remember not to give anyone any of the secrets unless you trust them, as they can be used to impersonate users and gain unauthorized access to the application.

## Implement sign in

Our next step is to allow people to sign in by adding a sign in button on the homepage that links to the GitHub OAuth verification page. Open `app/page.js` and insert the following below the Next.js logo (You should be able to find it by looking for an `<Image>` with `src=src="/next.svg"`).

```javascript
<a
  href={`https://github.com/login/oauth/authorize?scope=user:email&client_id=${process.env.NEXT_PUBLIC_GITHUB_OAUTH_ID}`}
  className={buttonStyle.button}
>
  Sign in with GitHub
</a>
```

The link will send people to a page where they can authorize the OAuth app’s access to their account information to allow the app to verify their identity. You might notice `className` contains a style that does not currently exist. We will fix this next. In `/app`, create a file named `button.module.css` and paste the following in.

```css
.button {
  z-index: 2;
  margin: 10px;
  transition-duration: 0.2s;
  display: inline-block;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 6px;
  white-space: nowrap;
  padding: 5px 16px;
  font-size: 14px;
  line-height: 20px;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  color: #24292e;
  background-color: #fafbfc;
}

.button:hover {
  background-color: #f3f4f6;
}

.button:focus {
  outline: none;
  border: 1px solid #c0d3eb;
  box-shadow: 0 0 0 1px black;
}

.button:active {
  background-color: #edeff2;
}
```

This just provides some simple styling for the button. In order to use it, we need to import it in `page.js`. Add this line to the top of `page.js`.

```jsx
import buttonStyle from './button.module.css'
```

To get the layout correct, we also have to add this to `.center` in `page.module.css`.

```css
flex-direction: column;
```

Now, run `npm run dev` and go to `http://localhost:3000`. You should see this:

![Social Sso In Next Js guide illustration](./247a788c35e5ea1c9dd8c876cbac8cded81fb1ff-3840x2160.png)

If you click “Sign in with GitHub,” you should be redirected to a GitHub page asking you to authorize your OAuth app. However, if you click authorize, you will get a 404 error. That is because we have not implemented a callback page yet, which we will do next.

## Creating a callback

Before we start this step, a bit of explaining is required. You might have seen OAuth flows implemented differently, and this is perfectly fine. There are multiple ways to handle OAuth codes and retrieve access tokens. In this case, we are using [Authorization Code Grant](https://oauth.net/2/grant-types/authorization-code), which is where the OAuth provider (GitHub in this case) sends a request to the specified callback URL (which we are implementing now) with a code. Then, the server sends a request to GitHub with the code, and GitHub responds with the access token. This is generally the most secure method, but for mobile apps or SPAs, it does not always work. With that explained, we will get started on implementing the callback.

You first want to create a folder named `callback` in app and a file named r`oute.js` inside callback. This tells Next.js’s filesystem router that `route.js` should handle API requests sent to `/callback`. Now, paste this into `route.js`:

```javascript
import jwt from 'jsonwebtoken'
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'

export async function GET(req) {
  const code = new URL(req.url).searchParams.get('code')

  if (!code) {
    return new Response('No code provided', { status: 400 })
  }

  try {
    const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
      method: 'POST',
      headers: {
        accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        client_id: process.env.NEXT_PUBLIC_GITHUB_OAUTH_ID,
        client_secret: process.env.GITHUB_OAUTH_SECRET,
        code,
      }),
    })

    const tokenData = await tokenResponse.json()

    const { access_token } = tokenData

    if (!access_token) {
      return new Response('GitHub login failed', { status: 400 })
    }

    const jwtToken = jwt.sign({ access_token }, process.env.JWT_SECRET, {
      expiresIn: '1h',
    })
    cookies().set('auth', jwtToken, {
      httpOnly: true,
      secure: process.env.NODE_ENV !== 'development',
      sameSite: 'lax',
      maxAge: 3600, // 1 hour
      path: '/',
    })
  } catch (error) {
    console.error(error)
    return new Response('Internal server error', { status: 500 })
  }
  redirect('/dashboard')
}
```

We will go through this step by step. First, we import a few different things:

- `jsonwebtoken` is for creating JWTs, which we use to store the userdata and allow us to verify that bad actors did not change it (we will do this later)
- `cookies` from `next/headers` is for setting cookies on the client. This function is an abstraction over the `Set-Cookie` HTTP header, hence the import location.
- `redirect` from `next/navigation` is for redirecting users. Similar to the `cookies` function, this function abstracts over HTTP responses by automatically responding with an HTTP 3xx status code (read: a redirect) with the `Location` header set to the value passed.

After that, we export a new function named `GET`, which takes `req` as a parameter. This function handles all HTTP requests to `/callback` with the HTTP method `GET`, which is the method used for typical requests that do not contain a body. `req` contains all of the information about the request.

The next part retrieves the code from the `code` query parameter in the URL. You can refer to the explanation at the start of this section to learn how this is used. If there is no code, the function returns a 400 error.

Now that we have the code, we send it back to GitHub to get the access token. After getting the response, we parse the JSON body and extract the access token. If there is no access token, another error is returned.

We sign the token to allow us to store it in a cookie with confidence that it cannot change without the JWT secret. Using the signed token, we set the `auth` cookie for the user. The parameters we passed are very important. `httpOnly` makes sure JavaScript cannot access the cookie’s value, `secure` makes sure that when deployed in production, the cookie cannot be sent over unencrypted HTTP, and `sameSite` prevents the cookie from being sent to third party websites. `sameSite=lax` is the default in modern browsers, but it is still a good idea to make it explicit.

Finally, we redirect the user to `/dashboard`. If you run this code, you should end up at another 404 at `/dashboard`. We will create the dashboard next.

## Creating a protected dashboard

Once again, we need to create a file named `dashboard` and a file inside it named `page.js`. Because this is a page rather than an API route, the naming is different. Copy the following into `page.js`:

```javascript
import { cookies } from 'next/headers'
import jwt from 'jsonwebtoken'
import { redirect } from 'next/navigation'
import buttonStyle from '../button.module.css'

export default async function Page() {
  const auth = cookies().get('auth')
  if (!auth) {
    redirect(
      `https://github.com/login/oauth/authorize?scope=user:email&client_id=${process.env.NEXT_PUBLIC_GITHUB_OAUTH_ID}`,
    )
    return
  }
  const user = jwt.verify(auth.value, process.env.JWT_SECRET)
  const response = await fetch('https://api.github.com/user', {
    headers: {
      Authorization: `token ${user.access_token}`,
    },
    cache: 'no-store',
  })
  const userdata = await response.json()
  return (
    <div>
      <h1
        style={{
          'text-align': 'center',
          'margin-top': '100px',
        }}
      >
        Welcome {userdata.name} to the dashboard!
      </h1>
      <a href="/logout" className={buttonStyle.button}>
        Logout
      </a>
    </div>
  )
}
```

Once again, we will go through this step by step. The imports are largely the same as the callback. The only difference is the addition of `../button.module.css`, which is the CSS file we created earlier for button styling.

This time, instead of a function named `GET`, because this is a page, we export a function named `Page`. Of course, because it is a default export in this case, the naming doesn’t really matter.

Next, we get the auth cookie. If no auth cookie is found, the user is not signed in, so we redirect the user to the sign in.

If there is an auth cookie, we verify the JWT contained in it. This is how we make sure the value was not tampered with. JWTs have a header, payload, and signature. The payload’s value can be accessed without the JWT secret. However, the JWT cannot be modified, as the signature is generated using the JWT secret and payload value. Therefore you need both of those to generate a valid signature. What we are doing here is both decrypting the payload and making sure the signature is valid.

Now that we have verified the JWT and extracted the payload, we use the access token in the JWT to request the user’s data from the GitHub API. The `cache` parameter disables Next.js’s AOT caching/static generation. Normally we would do this inside a `useEffect()` call, but because we are using [React Server Components](https://nextjs.org/docs/getting-started/react-essentials#server-components) with Next.js, this is the idiomatic way of using `fetch()` (remember that this renders once on the server and does not render on the client period). We then parse the response body to get the userdata.

After that, we just have some markup that renders a welcome message with the user’s name and a logout button. We use inline styles for the header because creating another CSS file just for two rules didn’t make sense. You might notice that the logout button links to `/logout`, which does not exist yet. We will fix that.

Tip: If you have lots of protected routes and want to avoid code repetition, you could implement the authentication as
middleware or just a function imported in the relevant routes

## Adding a logout route

This is pretty simple. The first thing to do is to create another route, just like what we did for `/callback`. Create a new folder in `app` called `logout` and a file called `route.js` in the new folder. Insert the following in the new file:

```javascript
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'

export async function GET(req) {
  cookies().delete('auth')
  redirect('/')
}
```

As you can see, this script is pretty simple. We just intercept GET requests to `/logout`, delete the cookie named `auth`, and redirect the user to the homepage. Note that if the user tries to log in again, it might seem as if they are still signed in, as GitHub will silently send the access token and redirect the user when they click login. However, if you implement a more complete sign in solution, this will allow users to sign in to another account with a different method.

That is all! You now have a basic system for OAuth authentication. However, there are a few issues.

## Problems with this Implementation

While this works, there are some problems:

- There is no protection against CSRF (Cross Site Request Forgery)
- There are no refresh tokens, and access tokens can last indefinitely (this is a limitation of GitHub OAuth apps)
- GitHub is currently the only sign in method (non OAuth sign requires many more security measures due to the need to store information in a database)
- There is support if issues arise with authentication

We could solve most of these problems, but it would take a significant amount of time (this tutorial is already almost 3,000 words) and increase maintenance. However, there is a better solution: you can use a service like [Clerk](/). Clerk is a user management platform that allows you to easily and securely implement most of the popular OAuth providers along with standard email/password sign in, [magic link/passwordless](/blog/magic-links), and even Metamask.

## Using Clerk for Authentication

Once again, run:

```sh
npx create-next-app@latest
```

and select the same choices as previously (any name, everything “no” except for the app router). Then, run:

```sh
npm install @clerk/nextjs
```

This installs the Clerk SDK for Next.js. Now, we need to set up a Clerk app. Go to [Clerk’s app creation page](https://dashboard.clerk.com/apps/new) (create an account if you did not already) and go through the configuration. For authentication providers, you can stick to just GitHub again or add as many providers as you want. It doesn’t change the process, and you can change it later. After that, you should be redirected to a page where you see a snippet containing `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY`. Copy this and paste it into a new file named `.env.local`. This includes the environment variables that store your public and private Clerk keys.

To allow us to use Clerk React components in our project, we first need to insert the `<ClerkProvider>` component into `layout.js`. Replace all content in `layout.js` with the following:

```javascript
import './globals.css'
import { Inter } from 'next/font/google'
import { ClerkProvider } from '@clerk/nextjs'
const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ClerkProvider>{children}</ClerkProvider>
      </body>
    </html>
  )
}
```

`<ClerkProvider>` provides the context necessary to allow Clerk components to function properly, and due to it being `layout.js`, it is inserted into every page.

Next, we need to create the sign in button, just like in the first version. Open `page.js` in `app` and insert this below the Next.js logo (the image with `src="/next.svg"`):

```javascript
{
  auth().userId ? (
    <a href="/dashboard" className={buttonStyle.button}>
      Dashboard
    </a>
  ) : (
    <SignInButton mode="modal" redirectUrl="/dashboard">
      <button className={buttonStyle.button}>Sign In</button>
    </SignInButton>
  )
}
```

This checks if the user is signed in. If they are, it shows a link to the dashboard, and if not, it shows a button to sign in. To make this work, you will also need to import two things at the top of the file:

```javascript
import { SignInButton, auth } from '@clerk/nextjs'
import buttonStyle from './button.module.css'
```

The first line contains the functions and components needed from the Clerk SDK, and the second is for the styling. You will want the same styling as in the previous version, so create a new file named button.module.css and insert this into it:

```css
.button {
  z-index: 2;
  margin: 10px;
  transition-duration: 0.2s;
  display: inline-block;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 6px;
  white-space: nowrap;
  padding: 5px 16px;
  font-size: 14px;
  line-height: 20px;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  color: #24292e;
  background-color: #fafbfc;
}

.button:hover {
  background-color: #f3f4f6;
}

.button:focus {
  outline: none;
  border: 1px solid #c0d3eb;
  box-shadow: 0 0 0 1px black;
}

.button:active {
  background-color: #edeff2;
}
```

Then, add this to `.center` in `page.module.css`:

```css
flex-direction: column;
```

Now sign in should work, but we still need to implement the dashboard. First, we need to create a JavaScript file at the project root named middleware.js (make sure to put this at the project root, not/app). Paste the following in the new file:

```javascript
import { authMiddleware } from '@clerk/nextjs'
export default authMiddleware()

export const config = {
  matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'],
}
```

This is a basic setup for the [authentication middleware](/nextjs-authentication). You can configure it more to exclude specific routes, but this should work in most cases.

The next step is to create a folder called `dashboard` and a file named `page.js` inside it, just like with the implementation we already made. Inside the file, paste this:

```javascript
import { currentUser, RedirectToSignIn, SignOutButton } from '@clerk/nextjs'
import buttonStyle from '../button.module.css'

export default async function Page() {
  const userdata = await currentUser()
  if (!userdata) {
    return <RedirectToSignIn />
  }
  return (
    <div>
      <h1
        style={{
          'text-align': 'center',
          'margin-top': '100px',
        }}
      >
        Welcome {userdata.emailAddresses[0].emailAddress} to the dashboard!
      </h1>
      <SignOutButton>
        <button className={buttonStyle.button}>Logout</button>
      </SignOutButton>
    </div>
  )
}
```

We will go through this step by step.

First, we import some packages.

- We import multiple different functions and components from the Clerk SDK. The first, `currentUser()`, helps us get the current user’s information. The second, `RedirectToSignIn`, not to be confused with the function `redirectToSignIn`, which is also exported, is a component that redirects the user to a sign in page. Finally, we have `SignOutButton`, which creates a button to allow the user to log out.
- `buttonStyle` is just CSS from our `button.module.css` file, which we use for the log out button.

Next, we export a function called `Page`, which has been explained previously.

After that, we use `currentUser()` to get the user’s information. If it does not exist (meaning the user is signed out), we redirect to a sign in page using a client side redirect.

Finally, using the userdata, we return markup containing a header with the user’s email and a button to log out.

Now, sign in, the dashboard, and sign out should all work.

## Easy SSO

That’s it! You now should have two implementations of OAuth authentication, one that is hand built and more limited and one that is built with Clerk and more feature rich. If you want to learn more about Clerk, check out the [Clerk Docs](/docs). I hoped you learned something, and thanks for reading!

Interested in exploring more? Look into [Next.js Magic Links](/blog/magic-links) for a seamless, passwordless authentication experience in your Next.js apps.

---

# How We Roll – Chapter 6: User Profile
URL: https://clerk.com/blog/how-we-roll-user-profile.md
Date: 2023-06-23
Category: Company
Description: How We Roll is a deep dive into how Clerk implements authentication. This chapter explores how we help developers ship a fully-featured account management UI.

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, roll) authentication at Clerk.

## Chapter 6: User Profile

Nothing is more frustrating than when a platform collects your information to create a profile for you, but doesn’t allow you to see what data you gave them, much less make any edits to your data without an extensive phone call or email chain. With that being said, building out an account management dashboard requires a good chunk of time to get right (think building out logic and UI components, in addition to the necessary security checks to protect users and their data), so it makes sense why some companies would push this feature off for later.

Our goal here at Clerk is to make it quick and easy for you to spin up a fully-authenticated, fully-featured application. This is why we make every effort to identify the most difficult, tedious, or time-consuming parts of standing up an authenticated app and package these features into components. One example of this is the `<UserProfile />` component, which allows you to stand up a fully featured account management UI just by dropping it into your code.

### Self service

Giving your users control over their accounts is great way to reduce support traffic and increase user satisfaction. Clerk’s `<UserProfile />` [component](/docs/component-reference/user-profile) gives your users autonomy over their data by allowing them to:

- Update their contact information, including name, email, and phone number
- Add additional login methods such as email, phone, and OAuth providers
- Change their password
- Add additional security measures like MFA or SMS OTP
- Delete their account

Implementing a self-serve feature may seem simple, but security must also be taken into consideration. For instance, a user should not be able to add an email without verifying that they own it. Additionally, the user should not be able to use the email until it has been verified. Finally, if the newly added email becomes the primary email address, the prior primary email should be alerted to the change.

We understand that this is a lot to build, which is why we baked these complexities into the `<UserProfile />` [component](/docs/component-reference/user-profile). It saves developers time and makes users happy, win/win!

### MFA / TOTP

Adding MFA to a user's account is a complex undertaking that involves the following steps:

1. Allow the user to choose which MFA option they want to use, such as application authentication
2. Enable the user to scan a QR code or manually type a code into their preferred MFA application
3. Require the user to provide a code provided by the MFA application or device
4. Provide backup codes in an easily accessible manner

When using Clerk’s `<UserProfile />` [component](/docs/component-reference/user-profile), developers can enable MFA / TOTP on with a single click in the dashboard. If you want to learn more about how Clerk handles MFA check out [chapter 3 of how we roll](/blog/how-we-roll-multifactor).

### Security

Our Clerk `<UserProfile/>` provides baked in security features such as listing all active devices, and the ability remotely log out a device if the user doesn’t recognize it.

![How We Roll User Profile guide illustration](./4258d0868dc77144b4d4cb9182f86801d31cd434-1826x1198.png)

This feature ensures that users can keep track of if there are any old or unknown devices with access to their account, but is also immensely helpful in keeping a user's data safe if one of their devices becomes lost or compromised.

### Summary

Account management is a critical and complex element of any application, and it doesn't have to be something you build from scratch. Clerk's `<UserProfile/>` component makes providing your users with a fully functional account management UI a matter of adding a few characters to your app, so you can focus on the core functionality of your application.

Check out the [Clerk Docs](/docs/component-reference/user-profile) to learn more about the `<UserProfile/>` component!

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- [How We Roll – Chapter 10: Roundup](/blog/how-we-roll-roundup)

---

# How to Authenticate API Requests with Clerk & Express
URL: https://clerk.com/blog/how-to-authenticate-api-requests-with-clerk-express.md
Date: 2023-06-16
Category: Guides
Description: In this tutorial, we'll explore how to use Clerk with Express to authenticate API requests using middleware.

APIs are essential for building powerful applications that can communicate and share data with other systems.

However, with great power comes great responsibility: it's critical to ensure that only authorized users can access your API, and that requests are properly authenticated and verified. Failure to do so can lead to serious security breaches, data leaks, and other vulnerabilities that can compromise the integrity of your application and put your users at risk.

In this tutorial, we'll explore how to use Clerk with Express to authenticate API requests using `ClerkExpressWithAuth()` and `ClerkExpressRequireAuth()` middleware, and build a secure and robust backend for your application. Let's get started!

## Always authenticate

When developing an API, especially in Express.js or any other framework, it's important to authenticate requests for a number of reasons:

1. **Security**: The most important reason is to maintain the security of your application. By authenticating API requests, you ensure that only authorized clients or users can interact with your API. This reduces the potential for malicious actions such as data theft, unauthorized modification, or even denial of service attacks.
2. **Access Control**: It allows you to control who can access certain resources and operations in your API. For instance, certain resources might only be available to admin users, while others are available to all authenticated users.
3. **Rate Limiting**: When you authenticate a user, you can associate them with a specific usage quota. This can be used to implement rate limiting, preventing any single user from overloading the server with requests.
4. **Data Accuracy**: In many cases, your API's operations will be tied to a specific user's data. For example, a "get user profile" endpoint would need to know which user's profile to retrieve. Authentication provides a way to associate requests with users.
5. **Audit and Logs**: It allows you to keep track of who did what and when. This is very useful when you need to audit the usage of your system.

Implementing express authentication or Node.js authentication is vital for maintaining the integrity, security, and reliable operation of your APIs.

That being said, there might be some API routes that you intentionally leave unauthenticated for various reasons. For instance, a login or registration route needs to be unauthenticated so that users can authenticate or create an account. Similarly, you might provide some public data through your API that doesn't require authentication.

But you should default to authentication. Consider it a component of building as you plan out epics or sprints on APIs. But adding auth doesn’t have to be particularly challenging. You can build this out yourself with middleware functions, but like a lot of elements in authentication, it’s better to use specialized components.

Let’s go through two of these we have at Clerk, `ClerkExpressWithAuth()` and `ClerkExpressRequireAuth()` to see how we can set these up Express authentication and call these endpoints from a client.

You can check out all the code for this tutorial in this [repo](https://github.com/argotdev/express-authentication).

## Authenticating Express API endpoints with Clerk

Before we get to the Clerk specifics, it’s good to define two components of API methods in Express (and elsewhere) that are fundamental concepts to how authentication will work: *callbacks* and *middleware*.

A ***callback*** function is a function that is passed to another function as a parameter and then invoked by that function at a later time. Callbacks are heavily used in Node.js because it's designed to be asynchronous and non-blocking. When performing I/O operations like making HTTP requests, Node.js can start the operation and then continue executing other code without waiting for the operation to complete. When the operation is complete, the callback function is called with the result.

***Middleware*** functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. Middleware functions can perform tasks like modifying the request or response objects, ending the request-response cycle, or invoking the next middleware function in the stack.

In Express, middleware functions are often used as callbacks to handle HTTP requests. When you define a route in Express.js, you provide a callback function that's called whenever a client makes a request to that route. This callback function is also a middleware, because it has access to the `req`, `res`, and `next` objects.

```jsx
app.get('/example', function (req, res, next) {
  // This function is a middleware and a callback
})
```

So, in this sense, middleware functions are a specific type of callback. They're callbacks that are designed to be used in the context of an HTTP request to an Express.js server.

This is what we’re going to do with Clerk. We’re going to use one of two authentication middleware functions as a callback for the request to our API endpoint. Those two middleware functions are:

1. `ClerkExpressWithAuth()` is a lax authentication middleware that returns an empty auth object when an unauthenticated request is made.
2. `ClerkExpressRequireAuth()` is a strict authentication middleware that raises an error when an unauthenticated request is made.

There are subtle but important differences between these two. Let’s go through them.

### Using ClerkExpressWithAuth()

`ClerkExpressWithAuth()` is lax in that when it fails, it still returns an object, not an error.

Let’s get some code up and running to showcase this function. We’ll create a directory called ‘backend’ and make that the current directory:

```bash
mkdir backend && cd backend
```

With that done, we’ll start installing our dependencies for this code. If you don’t already have it, you’ll also need node as this is the runtime we’re building upon. You can grab the latest build from [here](https://nodejs.org/en).

Then you can run `npm init` to create a package.json in that directory. With that we can use npm to install:

- [Express](https://expressjs.com), which is the web framework for Node.js we’re going to use. Express is a great option for running node servers because it’s fast, minimal, and unopinionated.
- [dotenv](https://www.npmjs.com/package/dotenv), which is the node package you need to read environmental variables in node.
- [@clerk/clerk-sdk-node](https://www.npmjs.com/package/@clerk/clerk-sdk-node) is the Node.js SDK for the Clerk user management platform.
- [cors](https://www.npmjs.com/package/cors) allows us to easily call the endpoint from a client

```bash
npm install express dotenv cors @clerk/clerk-sdk-node
```

When they are installed, create a file in your `with-auth` directory called `app.js`:

```bash
touch app.js
```

Then create a `.env` file in the same directory:

```bash
touch .env
```

This is where you’re going to store your `CLERK_API_KEY`. You can find this in your dashboard. Because you are building these routes on the backend, you can use your secret key:

![Clerk Secret Key](./c5601e5fd15a61e893bfb2d1a7aea4df6eea06f5-2056x442.png)

Then open this directory with your IDE. If you are using VS Code, you can just type `code .` and you’ll get a window ready in that directory.

Add your secret key to your .env file after `CLERK_API_KEY=key-goes-here`. Add the following code to `app.js`:

```jsx
import 'dotenv/config' // To read CLERK_API_KEY
import { ClerkExpressWithAuth } from '@clerk/clerk-sdk-node'
import express from 'express'
import cors from 'cors'
const port = process.env.PORT || 3000

const app = express()
app.use(cors())
// Use the lax middleware that returns an empty auth object when unauthenticated
app.get('/protected-endpoint', ClerkExpressWithAuth(), (req, res) => {
  res.json(req.auth)
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})
```

Let’s work through this line by line.

- Firstly we have all our imports:
  - `import "dotenv/config"` imports the "dotenv" package and automatically runs its `config` function. This package reads environmental variables from the `.env` file and adds them to `process.env`. Here we need it to access a `CLERK_API_KEY` environment variable.
  - We import `ClerkExpressWithAuth` from the "@clerk/clerk-sdk-node" package. This function is middleware for Express.js that handles authentication with Clerk.
  - We import `express` from the Express.js package
  - `import cors from "cors"` imports the "cors" package, a package used for enabling Cross Origin Resource Sharing (CORS). We’ll need this to aid calling the endpoint from our client.
- We then set a constant `port` to the value of the `PORT` environment variable if it's set, otherwise it defaults to `3000`.
- `const app = express()` creates a new Express application. The application is what is going to run our server.
- `app.use(cors())` adds the CORS middleware to the Express application, enabling CORS.
- `app.get(…)` defines a route for the path "/protected-endpoint" on the Express app. This route has two middleware functions:
  - `ClerkExpressWithAuth`: This is the function that checks the authorization of the incoming request. If the request is authenticated, it sets `req.auth` to an object representing the authenticated user.
  - `(req, res) => { res.json(req.auth); console.log(res.json); }`: This is an anonymous function that takes the incoming request and outgoing response as arguments. It sends a JSON response with the `auth` object from the request, and then it logs the JSON response function to the console.
- The final `app.listen(…)` part of the code starts the server and makes it listen for incoming connections on the specified port. It logs a message to the console indicating that the server is running and listening on that port.

Let’s run this:

```bash
node app.js
```

You should now see that message from in your `app.listen(…)` terminal:

```bash
Example app listening at http://localhost:3000
```

Great! You have a working endpoint. Let’s call that endpoint (`http://localhost:3000/protected-endpoint`) from Postman to see what it returns:

```json
{
  "sessionClaims": null,
  "sessionId": null,
  "session": null,
  "userId": null,
  "user": null,
  "actor": null,
  "orgId": null,
  "orgRole": null,
  "orgSlug": null,
  "organization": null,
  "claims": null
}
```

As we said above, `ClerkExpressWithAuth()` returns “an empty auth object when unauthenticated.” Now, you have a conundrum—you need an authenticated user to check this really works. To do that, we’ll create a quick React frontend client that calls `/protected-endpoint` after authenticating a user.

Keep that app running and open up another terminal. If it opens up in the same directory, make sure you cd .. up a level (you don’t want to create your frontend React app in a subdirectory of your backend—headaches will ensue).

We’ll first install create-react-app to help us (funnily enough) create a react app:

```bash
npm install create-react-app
```

Then run `npx create-react-app my-app` where my-app is the name of your app. Here we’ll go with auth-frontend:

```bash
npx create-react-app frontend
```

Then we’ll `cd frontend` to get into that directory and open with our IDE (again using `code .` if using VS Code).

Again, we’re going to add Clerk to this project, this time using`@clerk/clerk-react`, which is the Clerk React SDK.

We’ll also want to install `isomorphic-fetch` and `es6-promise` to polyfill the Fetch API for browsers that don't support it:

```bash
npm install @clerk/clerk-react isomorphic-fetch es6-promise
```

Like with the backend, you are going to need your Clerk API key. This time though you are going to use your public key as we’re authorizing a frontend client:

![Clerk Publishable Key](./60a107564b24f529282c1cda0eaebdfb50345894-2072x360.png)

Create a .env file and then add that key to it like this: `REACT_APP_CLERK_PUBLISHABLE_KEY=key-goes-here`.

Now go to the src/App.js file, remove the boilerplate entirely and add this code:

```jsx
import React from 'react'
import './App.css'
import { ClerkProvider, SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'
import Auth from './auth'

if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) {
  throw 'Missing Publishable Key'
}

const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY

function App() {
  return (
    <ClerkProvider publishableKey={clerkPubKey}>
      <SignedIn>
        <Auth />
      </SignedIn>
      <SignedOut>
        <RedirectToSignIn />
      </SignedOut>
    </ClerkProvider>
  )
}

export default App
```

We won’t go through this line by line because we’ve taken it entirely, with one exception, from our docs on [getting started with React](/docs/quickstarts/get-started-with-create-react-app). Head there to learn more about Clerk and React.

That one exception is that we’ve swapped out the `<Welcome />` component in the documentation within the `<SignedIn></SignedIn>` component for an `<Auth />` component. Within the src directory add `auth.js` and add this code:

```jsx
//src/auth.js

import fetch from 'isomorphic-fetch'
import React, { useState, useEffect } from 'react'

import { useAuth } from '@clerk/clerk-react'

function Auth() {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
  const { getToken } = useAuth()

  useEffect(() => {
    const fetchData = async () => {
      try {
        const token = await getToken()
        const response = await fetch('http://localhost:3000/protected-endpoint', {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${token}`,
            mode: 'cors',
          },
        })

        if (!response.ok) {
          throw new Error('Network response was not ok')
        }

        const result = await response.json()
        setData(result)
        setLoading(false)
      } catch (err) {
        setError(err)
        setLoading(false)
      }
    }

    fetchData()
  }, [getToken])

  if (loading) {
    return <div>Loading...</div>
  }

  if (error) {
    return <div>Error: {error.message}</div>
  }

  return (
    <div>
      <h1>Data from API:</h1>
      <p>{JSON.stringify(data, null, 2)}</p>
    </div>
  )
}

export default Auth
```

We will go through this line by line as it shows how you can pass that authentication token to the API endpoint.

- `import fetch from "isomorphic-fetch"` imports the `fetch` function from the `isomorphic-fetch` package.
- The next line imports the `React` default export and the `useState` and `useEffect` named exports from the `react` package. `useState` is a React Hook that lets you add React state to function components, and `useEffect` lets you perform side effects in function components.
- The final import is for the `useAuth` hook from the `@clerk/clerk-react` package. This hook provides access to Clerk's auth-related functionality.
- The `Auth` function component is then declared. Four pieces of state are created using the `useState` hook: `data`, `loading`, and `error` for storing API response data, the loading state, and any error messages, respectively. The `getToken` function is extracted from the `useAuth` hook to allow authentication token retrieval.
- We then create a `useEffect` hook to define a side effect that fetches data from an API when the component is first mounted and whenever the `getToken` function changes.
- Within the `useEffect` hook, the `fetchData` function tries to retrieve a token, then sends a GET request to our `/protected-endpoint`. If the request fails, it sets the error state and stops loading. If it succeeds, it sets the data state to the response data, and stops loading.
  - The critical part of this is the line `Authorization: Bearer ${token}`. Here, we’re passing the authorization token from our now-signed-in-user to our `/protected-endpoint` to use in its own authentication.
- In the rendering part of the `Auth` component, it checks if the `loading` state is true, and if so, returns a "Loading..." message. If there's an error, it displays the error message. Otherwise, it displays the data fetched from `/protected-endpoint`.
- Finally we export the `Auth` component as the default export of this module. This allows the `Auth` component to be imported and used in other parts of the application.

And thus we import that `Auth` and call it within the `SignedIn` function so we can use the authorization token and pass it to `/protected-endpoint`. Within `/protected-endpoint`, the ClerkExpressWithAuth middleware will check whether it is a valid token, and, if so, return a full auth object:

```json
{
  "sessionClaims": {
    "azp": "http://localhost:3000",
    "exp": 1686337111,
    "iat": 1686337051,
    "iss": "https://keen-moray-98.clerk.accounts.dev",
    "nbf": 1686337041,
    "sid": "sess_2QvzpU7hY6lF5GQSjQQHckp8wps",
    "sub": "user_2Qbkhxfu7VCmvM4Xguez0fmMg1c"
  },
  "sessionId": "sess_2QvzpU7hY6lF5GQSjQQHckp8wps",
  "userId": "user_2Qbkhxfu7VCmvM4Xguez0fmMg1c",
  "claims": {
    "azp": "http://localhost:3000",
    "exp": 1686337111,
    "iat": 1686337051,
    "iss": "https://keen-moray-98.clerk.accounts.dev",
    "nbf": 1686337041,
    "sid": "sess_2QvzpU7hY6lF5GQSjQQHckp8wps",
    "sub": "user_2Qbkhxfu7VCmvM4Xguez0fmMg1c"
  }
}
```

Now, on the backend we have our `sessionId` and `userId` and `claims` to use as needed and we know our user is authenticated and allowed to use this API endpoint!

### Using ClerkExpressRequireAuth()

`ClerkExpressRequireAuth` works slightly different when a user is unauthenticated. Whereas `ClerkExpressWithAuth` just returned an empty auth object, `ClerkExpressRequireAuth` returns an error.

Swap out your code in your express app.js for this below:

```jsx
import 'dotenv/config' // To read CLERK_API_KEY
import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node'
import express from 'express'

const port = process.env.PORT || 3000
const app = express()

// Use the strict middleware that raises an error when unauthenticated
app.get('/protected-endpoint', ClerkExpressRequireAuth(), (req, res) => {
  res.json(req.auth)
})

app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(401).send('Unauthenticated!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})
```

Most of this code is the same as the `ClerkExpressWithAuth` example above. The differences are:

- We’re importing the `ClerkExpressRequireAuth` from the Clerk Node.js SDK
- We’re calling that `ClerkExpressRequireAuth` middleware within our app.get() function.
- We now have an error-handling middleware function. If an error occurs in any middleware function that is run before this one (here the `ClerkExpressRequireAuth`), this function will be called. It logs the stack trace of the error and sends a response with the HTTP status code `401`, indicating that the client must authenticate to get the requested response, along with the message `Unauthenticated!`.

And lo and behold, if you call this in Postman you’ll get a 401 and this message:

```
Unauthenticated!
```

This is safer as we aren’t even sharing the structure of our auth object.

If we now call this within our React app though, we do get our auth object because we are authenticated:

```json
{
  "sessionClaims": {
    "azp": "http://localhost:3000",
    "exp": 1686337111,
    "iat": 1686337051,
    "iss": "https://keen-moray-98.clerk.accounts.dev",
    "nbf": 1686337041,
    "sid": "sess_2QvzpU7hY6lF5GQSjQQHckp8wps",
    "sub": "user_2Qbkhxfu7VCmvM4Xguez0fmMg1c"
  },
  "sessionId": "sess_2QvzpU7hY6lF5GQSjQQHckp8wps",
  "userId": "user_2Qbkhxfu7VCmvM4Xguez0fmMg1c",
  "claims": {
    "azp": "http://localhost:3000",
    "exp": 1686337111,
    "iat": 1686337051,
    "iss": "https://keen-moray-98.clerk.accounts.dev",
    "nbf": 1686337041,
    "sid": "sess_2QvzpU7hY6lF5GQSjQQHckp8wps",
    "sub": "user_2Qbkhxfu7VCmvM4Xguez0fmMg1c"
  }
}
```

And with that, you can now authenticate any API endpoint in your Express apps.

## Fast, authenticated endpoints

With Express and Clerk you can get authenticated, production-ready APIs up in a matter of just a few minutes. There is more code in our client that for our endpoint. Using `ClerkExpressWithAuth()` or `ClerkExpressRequireAuth()` you can protect any endpoint and add express authentication or node authentication without the hassle of building it yourself.

This is what you need with authentication—you want it done quickly. That way it’ll actually get done rather than sitting in your backlog queue for months until a dev can get to it. Or an attacker can get to your unprotected endpoints.

Next steps? Check out the code for this tutorial [here](https://github.com/argotdev/express-authentication). Check out Clerk [here](/) and more about using Clerk for express and node authentication [here](/docs/request-authentication/nodejs-express), and how to take these security elements even further with the [options](/docs/request-authentication/nodejs-express#middleware-options). Learn how to set up Clerk within your client to make user management super simple [here](/docs/quickstarts/overview).

---

# How We Roll – Chapter 5: Customization
URL: https://clerk.com/blog/how-we-roll-customization.md
Date: 2023-06-16
Category: Company
Description: How We Roll is a deep dive into how Clerk implements authentication. This chapter covers the various ways developers can customize Clerk's UI components.

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, roll) authentication at Clerk.

## Chapter 5: Customization

When you build your brand, you spend hours making sure every color, font, and logo is exactly how you envisioned. When you integrate with a 3rd party product like Clerk, you want to make sure that your brand shines. Clerk empowers developers by offering:

- Highly customizable components
- Custom flows
- Themes for our hosted pages

In this chapter we are going to be talking about how to customize our drop-in components and why we wanted to treat it as a first class experience. Grab a drink and enjoy a deep dive into our `appearance` property.

### Clerk’s Appearance Property

When Clerk introduced customization, we wanted something that wasn’t an afterthought where only minimal items could be changed, like buttons or primary colors. We wanted developers to go as deep as required, and the appearance property allowed this by letting developers:

- Have access to entire themes, like dark mode, and the ability to create a custom theme
- Control the layout
- Have global control of the appearance
- Customize individual components
- Inherit from key branding like fonts, and element sizing
- Integrate with their current CSS method of choice

### Base Themes

The `baseTheme` allows a developer to create a theme for your brand, and can be reused across multiple projects. We provide a package called `@clerk/themes` that allows you to use prebuilt versions that were crafted by Clerk, like our dark theme or shades of purple:

```tsx
import { type AppType } from 'next/app'
import { ClerkProvider } from '@clerk/nextjs'

import { dark } from '@clerk/themes'

const MyApp: AppType = ({ Component, pageProps }) => {
  return (
    <ClerkProvider
      appearance={{
        baseTheme: dark,
      }}
      {...pageProps}
    >
      <Component {...pageProps} />
    </ClerkProvider>
  )
}
```

![How We Roll Customization guide illustration](./de3892f51d7ad303f57aea7dc00f088ab22cafbe-1200x630.png)

### Controlling the Layout

The default layouts for Clerk’s sign in and sign up components show the social buttons at the top, with other forms of authentication, like email, below. In similar fashion, when a user signs up for your application, by default, we show the optional fields. For some applications this makes sense, for others, not so much.

This is where our `layout` property can be used. Developers can move social providers, change the default look of the social buttons, hide optional fields, show links to help, privacy policy, and terms and conditions pages, and much more:

```jsx
<ClerkProvider
  appearance={{
    layout: {
      showOptionalFields: false,
      socialButtonsPlacement: 'bottom',
      socialButtonsVariant: 'iconButton',
      helpPageUrl: '/help',
      privacyPageUrl: '/privacy',
      termsPageUrl: '/terms',
    },
  }}
  {...pageProps}
>
  {/* ... */}
</ClerkProvider>
```

![How We Roll Customization guide illustration](./de36acd844d0309a5eb94a72f0916415763a7b51-1200x630.png)

### Global Customization

Not every application needs its own theme; it is possible to extend the Clerk `baseTheme` to fit with an application. Examples include globally setting some of the attributes, such as every `primaryButton` element having a green background and the text inside being yellow, or setting all text colors to the company’s brand color.

All of this can be done at the `ClerkProvider` level, allowing developers to speed up the customization of our components:

```jsx
<ClerkProvider
  appearance={{
    elements: {
      formButtonPrimary: {
        backgroundColor: 'green',
        color: 'yellow',
      },
    },
    variables: {
      colorText: 'red',
    },
  }}
  {...pageProps}
>
  {/* ... */}
</ClerkProvider>
```

![How We Roll Customization guide illustration](./799b8b17147919db39fba9c505f8a8b73847dec8-1200x630.png)

### Individual Components

Applications are built of components, and individual components may need to be styled in a specific way. For example the Clerk `<UserButton />` might be too small for your sidebar or navigation bar, or the `<UserProfile/>` may not need to show the sidebar.

You can apply the `appearance` property directly to individual Clerk components:

```jsx
import { UserProfile } from '@clerk/nextjs'

export default function Profile() {
  return (
    <div>
      <UserProfile
        appearance={{
          elements: {
            navbar: {
              display: 'none',
            },
          },
        }}
      />
    </div>
  )
}
```

![How We Roll Customization guide illustration](./12a76fb56aa7791c8bb545574e5ad0fdff4e9893-1200x630.png)

### Elements and Variables

We’ve talked a lot about the parts that make Clerk customization a first class experience, but the powerful parts are variables and elements. Whether you are globally styling or styling individual components, variables and elements are essential.

The `variables` property is used to adjust the general styles of the base theme, like colors, backgrounds, typography:

```tsx
import { ClerkProvider, SignIn } from '@clerk/nextjs'
import type { AppProps } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ClerkProvider
      {...pageProps}
      appearance={{
        variables: {
          colorPrimary: 'red',
          colorText: 'white',
        },
      }}
    >
      <Component {...pageProps} />
    </ClerkProvider>
  )
}

export default MyApp
```

The `elements` property is used for fine-grained theme overrides, and is useful when styling specific HTML elements. You can find the element to target by inspecting the HTML and looking for the class name.

## Summary

Clerk allows for extensive customization when integrating with third-party products, ensuring brand elements are upheld. Developers can customize individual components, control the layout, modify the global appearance, create custom themes, and adjust the style of base themes through the `appearance`, `baseTheme`, `layout`, `variables`, and `elements` properties, ensuring the brand's unique design and user experience are reflected in every interaction.

For an in-depth look at how to leverage the full power of customization with Clerk, check out the Component Customization [docs](/docs/component-customization/appearance-prop).

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- [How We Roll – Chapter 10: Roundup](/blog/how-we-roll-roundup)

---

# How We Roll – Chapter 4: Email Verification
URL: https://clerk.com/blog/how-we-roll-email-verification.md
Date: 2023-06-09
Category: Company
Description: How We Roll is a deep dive into how Clerk implements authentication. From codes to links to SSO, this chapter is about when and how we verify emails.

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, *roll*) authentication at Clerk.

## Chapter 4: Email Verification

Email verification is a foundational and reusable piece of modern authentication:

- **It’s used during sign-up:** usually to prevent spam accounts, or as a requirement before enrolling a user on a mailing list.
- **It’s used during sign-in:** as a workaround to forgotten password, or as an alternative to passwords altogether.
- **It’s used during account management:** as a mechanism for adding new emails or changing the email for an account.

Although many think of verification links or one-time passcodes (OTPs) as the dominant verification mechanism, both approaches have fallen out-of-favor.

Today, the fastest and most common way to verify emails is actually single-sign on (SSO)! Social SSO (like “Sign in with Google”) and enterprise SSO (like Okta) are already responsible for over half of email verifications, and their adoption continues to grow every year.

This chapter discusses when and how to verify emails, and the tradeoffs of each option. Learn how Clerk handles email verification!

### When to verify

There are two options for when to require email verification: immediately at sign-up, or sometime after completing the signup process.

The most popular approach is to verify immediately at sign-up, which ensures that users will have a valid email, and helps mitigate spam or bot accounts.

In some cases, developers might want to allow signing up without email verification. This is usually done to give users access to some features immediately or for a limited time without jumping through an extra step, also called the foot-in-the-door strategy, while still keeping the bulk of the application behind an email verification check.

To achieve this, developers can turn off verify at sign-up through the Clerk dashboard, then check for email verification in the application to allow access to certain features. The email verification information is available on the [Clerk `User` object](/docs/reference/clerkjs/user) which can be fetched using [the `useUser` hook](/docs/reference/clerk-react/useuser) on the client, or [the `users.getUser` method](/docs/references/backend/user/get-user) on the node SDK.

### How to verify

The core verification mechanism is to send a unique token to the user’s email address. The user will then give this token to the application, verifying that the user owns that email address.

We offer both verification links and one-time passcodes. Developers can enable one of them to enforce that strategy, or enable both and let the users choose during verification.

### One time codes

The more straightforward way to implement verification is with a randomly generated 6-digit code that the user manually types into the application.

Code verification offers a benefit over links - users don’t need to be signed in to their email account to access the application on a device. Users could be using a different browser or a shared or public device that they don’t want to log into their email account on. This is also the reason why codes are seen a lot more for phone verification.

### Links

Clerk will generate a unique link with a signed JWT when using verification links. This link takes the user to the application where Clerk validates the JWT and signs in the user.

The JWT carries the signup attempt information and is only valid for 10 minutes. If the signup was successful, clicking the link again shows this message instead of signing the user in again.

![How We Roll Email Verification guide illustration](./aa54595c3d97f0d6a8c3076695da5ca706e21083-944x734.png)

Verification links offer a streamlined user experience, but it’s not without tradeoffs. Security-conscious individuals and email clients are suspicious of links in emails, as they could be malicious phishing links or download harmful files. Security policies and training often teach us to be careful with links in emails.

While we offer email verification links, for the aforementioned reasons, we recommend that developers use verification codes in most cases.

### Single Sign-on

As mentioned earlier, Single Sign-On with social providers like Google and enterprise providers like Okta is actually responsible for the majority of email verifications. We ensure that the user experience of Single Sign-On is seamless across various providers with no compromises to security.

Clerk’s SSO uses the Open ID Connect protocol (OIDC), which provides an `email_verified` claim. Identity Providers are supposed to set this to `true` if they have verified the user’s email. Almost every SSO provider verifies emails, so if a user signs up with a social provider, a second email verification step is unnecessary.

**OIDC refresher:** OpenID Connect is an identity protocol built on top of the OAuth 2.0 framework. If a request scope
of OIDC is defined when initiating an OAuth flow, identity providers present the application an ID token along with an
access token on a successful sign-in. The ID token is a JWT that contains some user information like name, email, and
avatar, in the form of “claims”.

Some providers do not verify emails immediately. So if a user signs up with SSO and their email is not verified by the provider, Clerk enforces an additional email verification step.

Some providers do not adhere to the OIDC spec. We audit all providers we support to ensure they are adhering to the spec, and if not, what their own format looks like. For example, the ID token from one of the social providers contains a `verified` claim instead of `email_verified` as defined in the spec, so we check for that. If the provider does not tell us whether the email is verified or not, we assume it’s not verified and force an additional email verification step.

Ensuring SSO providers have verified the user’s email is critical. Clerk provides account linking out of the box, which means users can sign in to the same account using multiple SSO providers as long as the email is the same. However, unless every SSO login verifies the emails, the account could be left vulnerable to takeovers. A malicious user could create a new account on a service that does not verify emails immediately, and use it to log in to an application as someone else. We are very careful with auditing every provider we work with to make sure developers don’t have to worry about the nuances across various providers.

### Summary

Email verification may seem like a straightforward task, but it is a common authentication process on the web that significantly affects both the user experience and application security. Clerk provides multiple options out of the box for developers to customize when and how they enforce email verification.

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- [How We Roll – Chapter 10: Roundup](/blog/how-we-roll-roundup)

---

# Secure Authentication in Next.js with Email Magic Links
URL: https://clerk.com/blog/secure-authentication-nextjs-email-magic-links.md
Date: 2023-06-06
Category: Guides
Description: In this guide, you will learn how to implement email magic links in Next.js.

Traditional username and password systems are ubiquitous but mostly suck. Every user needs a complicated random 8-20 character password that they can’t possibly remember for every site. Password managers make this easier, but they are ultimately just papering over the cracks.

Added to this cognitive load for users is the cognitive load for developers, who have to implement these systems securely or constantly worry about their sites becoming targets for malicious activity.

Imagine if you could simplify the user experience, decrease your system’s attack surface, and reduce your workload when it comes to user authentication. This is the promise of [magic links](/blog/magic-links), a powerful approach to passwordless authentication that is rapidly gaining popularity in the world of web development.

Here we want to show you not just the benefits of magic links but how exactly they work, going through an implementation process in Next.js. We’ll also show you why, like most authentication patterns, you don’t want to do this all yourself and how Clerk can help you, just like magic!

## Magical magic links

So, why use magic links? Magic links can greatly improve user experience in several ways:

1. **Ease of use**: Magic links simplify the login process, as users just need to click a link sent to their email to authenticate themselves. They don’t have to remember any usernames or passwords.
2. **Security**: Since there are no passwords to guess, magic links can increase security. This can be especially beneficial for users who often reuse passwords or use weak passwords.
3. **Speed**: Magic links streamline the registration and login process. Rather than having to fill out forms, users just need to enter their email address, then check their inbox and click a link.
4. **Reduced friction**: Magic links eliminate the common frustration of forgotten passwords and the need for password reset processes. 5.**Mobile-friendly**: Typing passwords on mobile devices can be challenging, especially for complex or long passwords. With magic links, users simply click a link in their email, which is much easier on a mobile device.
5. **Trust**: When used properly, magic links can build trust, as they demonstrate a commitment to both user convenience and security.

There are downsides. For one, the user obviously needs to have access to their email. Plus, there is the slight friction element of the user having to leap from the app to their email and back again. In theory, if the user’s email is compromised, an attacker can gain easy access to the app (you can get past this by using [two-factor authentication](/docs/authentication/custom-flows/multifactor) in your authentication flow).

Creating and validating time-sensitive tokens, like those used in magic links, typically involves the following steps:

1. **User Identification**: When the user requests a magic link, your application should first ensure that the email provided is valid and linked to a user account in your system. If the account exists, the server generates a unique, temporary token.
2. **Token Generation**: Generate a unique token using a secure method. This might involve using a secure random number generator or a library or function designed for generating secure tokens, such as JWT (JSON Web Tokens). The token should be associated with the user’s account in your database, along with a timestamp indicating when it was created.
3. **Time-Sensitive Mechanism**: Attach an expiry time to the token. This could be a specific expiry date/time or a duration after which the token will expire. This is usually stored along with the token in the database.
4. **Email Delivery**: Send an email to the user containing the magic link. The link should point to your website or app and include the token as a parameter.
5. **Token Validation**: When the user clicks the magic link, your application should validate the token. This involves checking that the token exists in your database, is linked to a user, and has not expired. If all these checks pass, the user is authenticated.
6. **Token Deletion/Invalidation**: Once a magic link has been used or has expired, it’s important to invalidate it so that it cannot be used again. This can be done by deleting the token from your database or marking it as invalid.

OK, so that’s magic links at a high level. How do you implement them in an application? Let’s go through two ways to do this. Firstly, we’ll show how you can do this with minimal additional libraries in Next.js to show what is required to generate, send, and validate time-sensitive tokens such as magic links. Then we’ll go through how you can implement them quicker and more securely with Clerk.

## Build your own magic links in Next.js

We need to expand the high-level flow above into more granular detail for what we need from our application:

1. **The user enters their email**: The user will enter their email address, which you’ll send to your backend.
2. **Generate a unique token**: On your server, generate a unique token tied to the user’s email. This can be a JWT, a UUID, or some other kind of unique identifier.
3. **Send an email with the magic link**: Include the unique token in the magic link and email it to the user.
4. **User clicks the link**: The user will click the link, which sends the token back to your server.
5. **Verify the token**: On your server, verify that the token is valid and matches the user’s email.
6. **Create a session**: If the token is valid, create a new session for the user and send it back to the client.
7. **Store the session on the client**: On the client, store the session (usually in a cookie or local storage) so that the user remains logged in.
8. **Authorize the user**: Whenever the user makes a request, check that they have a valid session.

So beyond Next.js, for this to work, we need:

- A way to generate and verify our tokens. In this instance, we’re going to use JWT for our tokens and use `jsonwebtoken` to generate and verify them.
- A way to send emails. We’ll use `nodemailer`. You’ll also need SMTP information for your email provider.
- A way to create cookies to store session data. We’ll use the `cookie` library here.

That’s all you need. Let’s first spin up a Next.js app called ‘magic-links’ as the bare bones of what we’ll create:

```bash
npx create-next-app@latest magic-links
```

You’ll be asked a bunch of questions. Here we’re not using TypeScript and neither are we using the App directory (which is the new, better way of using Next.js that we’ll use later. But it doesn’t play as nicely with some of the API routes we’re creating here).

After that we’ll install the necessary packages:

```bash
npm install jsonwebtoken nodemailer cookie
```

You can then run npm run dev to start the development server. At the moment all you’ll get at [http://localhost:3000](http://localhost:3000) is the regular Next.js start page:

![image1.png](./e31247c8534a6bc92acfb54d8be11422ff7c074e-1999x1264.png)

Obviously we need a login component as the first step. We’ll create a /components directory and add a login.js file:

```jsx
// components/login.js

import { useState } from 'react'

function Login() {
  const [email, setEmail] = useState('')

  const handleSubmit = async (e) => {
    e.preventDefault()
    const res = await fetch('/api/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ email }),
    })
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
      <button type="submit">Send Magic Link</button>
    </form>
  )
}

export default Login
```

So there are two main parts to this component. At the bottom we have the actual form a user will fill in with their email address. As they type their email in, the state of the `email` variable will change to contain their email address.

When the press ‘Send Magic Link,’ The `handleSubmit` function will be called. This function will call a backend api route, `/api/login`. We’re going to send a POST request to this endpoint with the email address in the body.

Let’s add this to our index page. Delete all the boilerplate code within that file and replace it with:

```jsx
// pages/index.js

import { Inter } from 'next/font/google'
import Login from '../components/login'

const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  return (
    <main
      className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}
    >
      <div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
        <Login />
      </div>
    </main>
  )
}
```

We’re importing the `Login` component and adding it to this page. Now a user will see this at [http://localhost:3000](http://localhost:3000):

![image8.png](./f92c06581c57df46dfbf7dbd31ce2dafcb0dc877-1999x1264.png)

If they were to add their email into that field and press ‘Send Magic Link,’ guess what would happen?

Absolutely nothing! Let’s make something happen. What we need is that `/api/login` the Login component calls. We’ll create a `login.js` file in the api directory. Though this is within the `pages` directory, it won’t be treated as a page by Next.js, it will act like an API endpoint:

```jsx
// pages/api/login.js

import jwt from 'jsonwebtoken'
import nodemailer from 'nodemailer'

export default async function handler(req, res) {
  const { email } = req.body

  // Create a magic link token
  const token = jwt.sign({ email }, process.env.JWT_SECRET, {
    expiresIn: '15m',
  })

  const transporter = nodemailer.createTransport({
    host: 'mail.example.com',
    port: 587,
    secure: false,
    auth: {
      user: 'username',
      pass: 'password',
    },
  })

  // Generate magic link
  const magicLink = `${req.headers.origin}/api/verify?token=${token}`

  await transporter.sendMail({
    from: '"Your Name" <your-email@example.com>', // sender address
    to: email, // list of receivers
    subject: 'Your Magic Link', // Subject line
    text: `Click on this link to log in: ${magicLink}`, // plain text body
  })

  res.status(200).json({ success: true })
}
```

This is where the first part of the magic of magic links happens. Let’s step through this to see what’s happening:

- First we’re importing the libraries we need, `jsonwebtoken` and `nodemailer`.
- Within our `handler` function, we’ll get the `email` from the body of the request.
- With that email as the payload, we’ll use the sign method from `jsonwebtoken` to create our token. There are two extra parameters we need to pass to sign:
  - A `JWT_SECRET`. You can create a secret (for these purposes, not for production) by running `openssl rand -base64 32` in the terminal to generate a key. You then store that key in a .env file in the root of the project for the project to read.
  - An expiresIn time. Here, we’ve set this to 15 minutes.
- Now we have our token, we need to send it to the user’s email address. Here we’re using the `createTransport` method from `nodemailer` to create an object called a `transporter` that contains all our (i.e. the sender) SMTP email information.
- We’ll then create the actual magic link, which will be the origin URL (our URL) with the token appended as a query.
- Then we’ll call `sendMail` on the `transporter` object to send the email to the recipient

Now if the user presses ‘Send Magic Link,’ they should get an email like this:

![image5.png](./e6395766363d25d1f351680920e1e2f63485d730-1999x221.png)

Now if they click on that guess what would happen?

Absolutely nothing!

We need an endpoint to verify the token and set a cookie on the client with the user's email. First, let’s create another file in the api directory, this one called `verify.js`:

```jsx
// pages/api/verify.js

import jwt from 'jsonwebtoken'
import { serialize } from 'cookie'

export default async function handler(req, res) {
  const { token } = req.query

  try {
    // Verify the token - this throws if the token is invalid
    const { email } = jwt.verify(token, process.env.JWT_SECRET)

    // The token is valid, so we create a session
    const sessionToken = jwt.sign({ email }, process.env.JWT_SECRET, {
      expiresIn: '1h',
    })

    res.setHeader(
      'Set-Cookie',
      serialize('auth', sessionToken, {
        httpOnly: true,
        secure: process.env.NODE_ENV !== 'development', // Use secure cookies in production
        sameSite: 'strict',
        maxAge: 3600, // Expires after 1 hour
        path: '/',
      }),
    )

    // Redirect the user to the homepage
    res.writeHead(302, { Location: '/secrets' })
    res.end()
  } catch (err) {
    // The token was invalid, return an error
    res.status(401).json({ error: 'Invalid token' })
  }
}
```

The top part of this is similar to the API route, but let’s step through the entire thing for clarity:

- First we’re importing the libraries we need, `jsonwebtoken` again and cookie for session management.
- Within our `handler` function, we’ll get the token from the query of the request.
- With that token as the payload, we’ll use the verify method from `jsonwebtoken` to verify our token. This again uses our `JWT_SECRET` that we signed it with to verify.
- If that’s a valid token, we’ll then create a session for the user, again using the `sign` method from `jsonwebtoken`. We set an expiresIn time of an hour. After that, our user will be logged out.
- We add the token to our cookie using `serialize` from the `cookie` library, then add the cookie to the headers of our result.
- We’ll then redirect the user to a logged-in-only page

That page, `/secrets` doesn’t yet exist. Let’s create it in the `/pages` directory:

```jsx
// pages/secrets.js

import { useEffect, useState } from 'react'
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export default function Secrets() {
  const [data, setData] = useState(null)

  useEffect(() => {
    // Fetch data from our API route
    fetch('/api/secure-endpoint')
      .then((res) => {
        // If the response was not ok, throw an error
        if (!res.ok) {
          throw new Error('Failed to fetch')
        }
        return res.json()
      })
      .then((data) => {
        setData(data)
      })
      .catch((err) => {
        console.error('An error occurred: ', err.message)
      })
  }, [])

  // Render data or loading message
  return (
    <main
      className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`}
    >
      <div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
        {data ? (
          <>
            <h1>{data.secret}</h1>
            <h2>{data.email}</h2>
          </>
        ) : (
          <p>This isn&apos;t a secret </p>
        )}
      </div>
    </main>
  )
}
```

This will conditionally render either a data object with the fields `secret` and `email` if the user is authenticated, or the text ‘This isn’t a secret’ if they aren’t. The data object comes from a call to our final api endpoint that we need to create, `secure-endpoint.js`:

```jsx
// pages/api/secure-endpoint.js

import jwt from 'jsonwebtoken'

export default function handler(req, res) {
  const { auth } = req.cookies

  if (!auth) {
    return res.status(401).json({ message: 'Unauthorized' })
  }

  try {
    const { email } = jwt.verify(auth, process.env.JWT_SECRET)

    // Now you have the authenticated user's email
    // Do your secure stuff here...

    res.json({ secret: 'This is a secret!', email })
  } catch (error) {
    res.status(401).json({ message: 'Unauthorized' })
  }
}
```

This authorizes the user by verifying with `verify` from `jsonwebtoken` the session token and, if the user is authenticated, passing back an object with a `secret` (‘This is a secret!’) and an `email`. Now if a user fills in their email and clicks on the link, they’ll be sent to the secret page with the `secret` and their `email` showing:

![image4.png](./ca4c4a91d3010cf0e8f4e308548af46cb6233c91-1999x1264.png)

That's it! With these routes, you now have a basic magic link authentication system.

## Using Clerk for your magic links

The above code works. It’s also a terrible idea.

We aren’t doing any error handling. We aren’t checking for any edge cases. We’re not overly protective of our JWT token. If an attacker learns your JWT secret, they can create valid tokens and impersonate any user. There’s no rate limiting. The cookie storage isn’t ideal.

Plus we have to have our own email server that is configured to send out a lot of transactional emails (which regular email providers don’t really like as they get punished for spam). And, yeah, we know, our login and authenticated pages aren’t exactly winning any design awards.

Basically, there are a number of issues with rolling your own magic links.

That’s why services like Clerk’s [Next.js authentication](/nextjs-authentication) exist – to deal with all of the above and make it much easier for developers to implement strong authentication frameworks such as magic links.

We’ll spin up a new Next.js app:

```bash
npx create-next-app@latest magic-links
```

Again, you’ll get the questions. Clerk is written for the latest developments in Next.js, so you can use the App Router.

After that all we need to install is Clerk:

```bash
npm install @clerk/nextjs
```

If we npm run dev now and go to [http://localhost:3000](http://localhost:3000) we again get a regular Next.js start page:

![image3.png](./4bb435f2579af449d2b3fd21d8e9fef9552cc92f-1999x1264.png)

Before we get to the code, we’ll also want to do some other set up. First, we’ll need our NEXT\_PUBLIC\_CLERK\_PUBLISHABLE\_KEY and our CLERK\_SECRET\_KEY. You can get both of these from your [Dashboard](https://dashboard.clerk.com/last-active?path=api-keys).

Add these to an .env file in the root of your project:

```sh
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY = pk_test_xxxx;
CLERK_SECRET_KEY = sk_test_xxxx;
```

We’ll also want to configure our Clerk set up to use magic links. We need to change two settings from the defaults in our dashboard. The first is to choose Email verification link as the authentication factor. To do that, go to **User & Authentication > Email, Phone, Username** in your dashboard:

![CleanShot 2023-06-05 at 15.57.39@2x.png](./540c62b637a385ef8cd77f9cdca5044807fbfe6b-3346x2116.png)

Then go to **Contact information** in that subsection and toggle on **Email address** and check **Email Verification Link**:

![CleanShot 2023-06-05 at 15.56.18 2@2x.png](./cc5d1162222b94bf1c5be87853f1e248bbdfb9d9-3346x2116.png)

Now we can start with the code. The first step is to wrap our entire Next.js application in the `<ClerkProvider>`:

```tsx
// app/layout.tsx
import './globals.css'
import { Inter } from 'next/font/google'
import { ClerkProvider } from '@clerk/nextjs'

const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body className={inter.className}>{children}</body>
      </html>
    </ClerkProvider>
  )
}
```

This is going to provide all we need to pass session and user information to Clerk for the authentication logic. This step is the same for any authentication pattern you are going to use with Clerk in Next.js.

The next step is to use Clerk to protect pages within our application. To do this, we’ll create a file in the `/src` directory. This will use regular expressions to pattern match against the pages you want to protect. Here, we’re going to protect all our pages:

```javascript
//middleware.ts

import { authMiddleware } from '@clerk/nextjs'
export default authMiddleware()
export const config = {
  matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'],
}
```

Now if you load up [http://localhost:3000](http://localhost:3000), you’ll be redirected to a login/signup page:

![image9.png](./8d71d81b4d43e75cc90dd58eb82a086bbcfac4d8-1999x1264.png)

A user enters their email address here and gets sent a link to click:

![image7.png](./b9be271aeb2174a5c010fa2b21b2cfc74dac7d07-1999x965.png)

Clicking on that link sends them back to [http://localhost:3000](http://localhost:3000), but now they can access the site again:

![image3.png](./4bb435f2579af449d2b3fd21d8e9fef9552cc92f-1999x1264.png)

Much easier (and much better looking signup pages and emails as well!)

## Better security and a user experience with magic links

Magic links can really help you streamline your sign up and sign in processes. They lessen the burden on your users while providing strong security for them and your application.

But implementing them manually puts the burden on your developers. Managing creation and validation of the tokens, sending emails (and maintaining the system to do so), then coding up the right modals, pages, error states, and edge cases is a huge hassle.

It’s worth developers going through and trying this manually just to see how magic links are implemented. But if you are looking for a production-ready option that you can incorporate into your app today, you can use [Clerk](/).

---

# How We Roll – Chapter 3: Multifactor
URL: https://clerk.com/blog/how-we-roll-multifactor.md
Date: 2023-06-02
Category: Company
Description: How We Roll is a deep-dive into how Clerk implements authentication. This chapter is on something you know and something you have: multifactor authentication!

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, *roll*) authentication at Clerk.

## Chapter 3: Multifactor

Multifactor authentication, or MFA, is the process of authenticating users in multiple different ways before granting access to their account.

It goes by many names. Technologists seem to have settled on \_multi\_factor authentication because, well, why limit ourselves to two? But *two* factor authentication is still common and the phrase is used interchangeably.

Within consumer products, though, we've seen the rise of two-*step* *verification:*

![Chapter 3: Multifactor screenshot](./53eba8b30ad84278ea863251368d8d3995ca372d-1458x430.png "Google calls the feature \"2-Step Verification\" or 2SV")

Both word substitutions make the concept a little easier to digest, so Clerk has also adopted this language for `<UserProfile/>` component.

Enough about names, though... How We Roll is for technical details, and naming is the easy part! (Hah.)

Just like [passwords](/blog/how-we-roll-passwords), best practices for multifactor authentication have been learned through a history trial-and-error. Let's see how Clerk handles it all!

## Self-serve, out of the box

Clerk provides multifactor authentication out of the box, which means it requires **zero** additional work. How so? The `<UserProfile/>` component includes a self-serve flow for users to configure multifactor authentication:

Users can choose between one-time passwords sent by SMS (SMS OTP) or time-based one-time passwords (TOTP). Once configured, they also receive backup codes in the event that access to their other factor is lost.

And `<UserProfile/>` works in tandem with `<SignIn/>`, so the next time a user signs in, they will be prompted to authenticate with their second factor. No custom code required!

If preferred, Clerk also provides `useUser()` and `useSignIn()` hooks, which enable developers to build custom flows for configuring multifactor authentication.

## Something you know, something you have

For multifactor authentication, Clerk mandates that each step satisfies a different *factor*, or type of evidence, for authentication. The two factors we offer are:

1. **Something you know –** also called a knowledge factor, is proof that you know something that only you should know, like passwords, security questions, and pins. By extension, it also includes access to another account which is presumed to require a password (like an email account to receive a one-time password, or a Google account).
2. **Something you have –** also called a possession factor, is proof that you are holding a physical device. SMS and time-based one-time passwords are both examples, as are newer strategies like passkeys.

It is critical for Clerk to use one example from each bucket. A one-time password sent by email (email OTP) can be a replacement for a password, but a SMS OTP cannot.

Similarly, if a user with multifactor authentication forgets their password, the "forgot password" flow cannot be used to bypass the second factor. Instead, after the user verifies their email, they will still be asked to provide a possession factor.

If a user with multifactor authentication completely loses access to either factor, Clerk cannot directly help that user regain access to their account. Instead, an application administrator can help facilitate account recovery through the Clerk dashboard.

## Mitigate SIM swaps at the application level or user level

SMS OTP is a controversial topic among security professions, and rightfully so. SMS is susceptible to a social engineering attack called a "SIM swap," where a telephone company is persuaded to issue a SIM card to an attacker for a victim's phone number.

The general consensus is that SMS OTPs add some degree of security, but a targeted attack has a high chance of success. Jack Dorsey [infamously fell victim](https://www.wired.com/story/jack-dorsey-twitter-hacked) to a SIM swap which helped an attacker gain access to his Twitter account.

Many argue that SMS OTP should be discontinued entirely. The challenge is that SMS is ubiquitous and convenient, so users are more likely to configure multifactor when SMS can be used.

At Clerk, we don't believe the answer is not one-size-fits all, so our solution is two-fold:

1. Developers can choose to disable SMS OTP at the application level.
2. Individual users can choose to disable SMS OTP at the user level. Even if a phone number is added to an account, SMS OTP must be explicitly enabled for it to be used as a possession factor.

![Mitigate SIM swaps at the application level or user level screenshot](./3fe377763fc8afcbdee8eee118573562d27bd121-2022x954.png "Clerk's dashboard allows developers to choose if SMS OTP is enabled")

## Summary

Multifactor authentication is an essential security feature that every application should offer, but it is essential that best practices are followed for knowledge and possession factors. Clerk's components and hooks provide those best practices for multifactor authentication out of the box.

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- [How We Roll – Chapter 10: Roundup](/blog/how-we-roll-roundup)

---

# Announcing A New Password Experience
URL: https://clerk.com/blog/a-new-password-experience.md
Date: 2023-05-19
Category: Company
Description: The team has been focused on making a first in class experience for your end users when it comes to passwords. Let's talk about the new features we introduced. 

It's time for an exciting announcement from our end, one that's been brewing for a while. While it may seem like a small step, we believe it's a giant leap towards an unparalleled user experience, especially when it comes to password security.

Our team has been hard at work, making your end users' experience first-in-class. We're thrilled to introduce a suite of new features that will take password management to the next level. Let's dive into the details!

## Password Reset Flow

Who hasn't forgotten a password at least once? Now, with our traditional password reset flow, users can reset their password with a single click. The best part? It ships with our [sign in component](/docs/authentication/sign-in) and syncs perfectly with our [Multi-Factor Authentication (MFA) products](/docs/authentication/custom-flows/multifactor), ensuring all necessary verification steps are complete before users are automatically signed back into your application.

## **Strong Passwords Verification**

In addition to our [HaveIBeenPwned](https://haveibeenpwned.com) integration, we now enable you to set a minimum strength requirement for all new passwords in your application. This added security layer is powered by the password strength estimator [zxcvbn-ts](https://github.com/zxcvbn-ts/zxcvbn).

With its ability to detect commonly used passwords and patterns such as dates, names, and common phrases, zxcvbn-ts ensures that your end users are protected from using weak passwords in your application. Now, stronger password security is not just an option, but a standard.

## **Additional Complexity Requirements**

For our [Business plan](/pricing) users and beyond, we're introducing the ability to enforce specific password requirements like special characters, numbers, and a mix of uppercase and lowercase letters. This will help your users to not just meet, but exceed your standards.

![Clerk dashboard password complexity policy options](./b7ea47b66fa674b5ccf0537b86492ccb73b2ca36-1696x1698.png)

## **Password Completion Guidance**

To take password requirements one step further, once you set password policies in your Clerk dashboard, you can even opt for users to be alerted to your length or complexity requirements via guidance cues. When users are setting their password, friendly messaging will appear below the input box that indicates the password policies you selected to help them create passwords that are robust and compliant.

We're excited about these new additions and can't wait for you to experience them. Here's to a better user experience for all! Want to learn more about "how we roll" passwords? Check out our [post](/blog/how-we-roll-passwords) that goes in depth about passwords at Clerk.

Let us know your thoughts on X [@clerk](https://x.com/clerk) or in the [Clerk Community](https://clerk.com/discord) on Discord.

---

# How We Roll – Chapter 2: Avatars
URL: https://clerk.com/blog/how-we-roll-avatars.md
Date: 2023-05-19
Category: Company
Description: How We Roll is a deep-dive into how Clerk implements authentication. In this chapter, we discuss why avatars should never be an afterthought.

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, *roll*) authentication at Clerk.

## Chapter 2: Avatars

We're focusing on avatars early in the series because too many applications treat them as an afterthought. But at the biggest companies in the world – the ones with full-time identity teams working to streamline every aspect of authentication – it's common to see avatars used to "level-up" the user experience.

![Chapter 2: Avatars screenshot](./fbba56b5223a378e591a77fe17f8fa2ee8df4062-3860x2056.png "Google uses avatars within their sign-in flow and as a button throughout their applications.")

At Clerk, we operate like an outsourced identity team, and we *love* bringing details like these to our customers. We obsess over authentication so our customers can focus on what truly differentiates their business.

Let's dive in to the full feature!

## Choosing avatars

There's an unfortunate reality when dealing with avatars: users don't like uploading their avatar directly. Forcing avatar upload during the sign-up flow would dramatically reduce conversion rates.

Thankfully, "social sign-in" providers like Google and Facebook provide access to the user's avatar through the [OpenID](https://en.wikipedia.org/wiki/OpenID) protocol. Moreover, when social sign-in is available, it's preferred by over 50% of users.

As a result, simply enabling *Sign in with Google* leads to most users automatically having their choice of avatar.

Of course, should they choose, users can always modify their avatar through Clerk's `<UserProfile/>` component, or developers can build their own flow with the `useUser()` hook.

### Beautiful default avatars

In the event that users do not provide an avatar, directly or indirectly, Clerk generates beautiful default avatars for every user.

We offers a variety of options, with initials or silhouettes in the foreground, and marbling or a solid color in the background. The marbling effect is built with the fantastic open source project [Boring Avatars](https://boringavatars.com).

## Avatars for the `<UserButton/>`

The most common place avatars are seen today is the top-right of an application. Clicking it opens a menu to manage account settings or sign out.

Clerk provides this functionality through a component called `<UserButton/>`.

![How We Roll Avatars guide illustration](./d67e359f62393528c1ab5bd353aa8f45d2dc5499-1506x880.png)

To better indicate this is a button without modifying the avatar itself, we allow developers to add a "shimmer" effect on mouseover:

## Avatars in the sign-in flow

Like Google, Clerk's `<SignIn/>` component displays the user's avatar during the sign-in flow.

This is primarily seen as a benefit to user experience, but it also has benefits in security. The idea is that users will grow accustomed to seeing their avatar during the sign-in process. If they ever see the wrong avatar, it will raise suspicion of a potential phishing attack.

![How We Roll Avatars guide illustration](./db878c278a10709c17dd3cfdd0f4ca7b0b5cf3a7-1298x1084.png)

## Summary

Though avatars may feel like a small feature, they bring a high degree of polish and professionalism to modern applications. Clerk's social sign-in integrations, beautiful default avatars, and prebuilt components all work together to make avatars easier than ever before.

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- [How We Roll – Chapter 10: Roundup](/blog/how-we-roll-roundup)

---

# How We Roll – Chapter 1: Passwords
URL: https://clerk.com/blog/how-we-roll-passwords.md
Date: 2023-05-19
Category: Company
Description: How We Roll is a deep-dive into how Clerk implements authentication. In this first chapter, we discuss passwords – the original form of authentication.

Welcome to How We Roll! This series is meant to help product owners, developers, and security professionals understand exactly how we implement (or, *roll*) authentication at Clerk.

## Chapter 1: Passwords

Many consider passwords to be the "original" form of authentication. They have been used in software since long before the internet existed and are championed for their ease-of-use.

Despite being such a common authentication strategy, implementing passwords is a surprisingly complex task. Decades of trial-and-error have taught us best practices for:

1. Choosing passwords
2. Changing passwords
3. Storing passwords
4. Migrating passwords

Let's learn how Clerk handles it all!

## Choosing passwords

Users can choose passwords in three different scenarios: signing up, changing their password, and resetting their password.

In each scenario, Clerk presents the password field:

This field is designed to provide feedback as the user types, and offers three variants of feedback:

### 1. Password is too short

As with every authentication factor, we first referenced [NIST 800-63B](https://pages.nist.gov/800-63-3/sp800-63b.html) to determine our password requirements. The National Institute of Standards and Technology (NIST) maintains this document specifically to help authentication professionals maintain the security of digital accounts.

There, we learned that 8 characters is the optimal minimum password length, and so we apply this requirement across every Clerk application.

### 2. Password has been breached

NIST guidance also states that passwords which have been breached should not be used again. Password database leaks are unfortunately all-too-common, and many of those databases store passwords in an unsafe manner.

As a result, billions of passwords have been breached and cannot be used again. To determine whether a password can be used, Clerk leverages the well-maintained corpus from [Have I Been Pwned](https://haveibeenpwned.com).

### 3. Password is too weak

Though it's not suggested by NIST, we implement [zxcvbn](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler) to measure password strength as a user types. zxcvbn is a battle-tested complexity estimation algorithm, originally developed within Dropbox.

We allow developers to enforce a minimum level of complexity (low, medium, or high), as determined by zxcvbn.

### Customizing requirements

Within Clerk's dashboard, developers can customize the requirements for users choosing a password:

![How We Roll Passwords guide illustration](./b7ea47b66fa674b5ccf0537b86492ccb73b2ca36-1696x1698.png)

Although not recommended because they frustrate users and because NIST advises against them, this screenshot shows how Clerk also allows LUDS-based password strength requirements (lowercase, uppercase, digits, symbols).

## Changing passwords

When changing or resetting passwords, we help users keep their accounts secure with two requirements:

1. The user must authenticate first, including with multifactor authentication if it is enabled on their account. The helps prevent attackers from claiming an account they discover is signed-in on a public device.
2. The user must be given the option to sign out of other devices. This stops attackers who may already have access to an account.

Here's an example in Clerk's forgot password flow:

## Storage

We use the industry-standard, one-way password hashing function called [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) to hash passwords before they are saved to our database. This is essential to prevent passwords from being leaked, *even in the unlikely event that Clerk's database leaks.*

Counterintuitively, bcrypt adds security by being computationally expensive. Trying to break a bcrypt hash by brute-force is impractical, because it would cost too much money (e.g. trying every possible combination of characters).

Although bcrypt is the standard today, it's important to recognize that the standard changes with some regularity. We monitor those changes and will update our preferred strategy as needed.

## Migrations

Although bcrypt is our preferred hashing algorithm, we support importing passwords that previously used a wide variety of alternative hashing algorithms, like argon2, scrypt, and pbkdf2\_sha256.

These hashes will stay in their original format until the user signs in again with their password. At that time, we will replace the hash to use bcrypt going forward. This ensures that even if passwords are migrated from a weaker format, they are continually upgraded to a modern best-practice.

## Summary

Though simple in concept, implementing passwords for authentication is a complex task. Clerk's components and APIs offer best practices in security and user experience out-of-the-box, so developers can stop worrying about authentication and focus on what truly differentiates their business.

## How We Roll Series Index

- [How We Roll – Chapter 1: Passwords](/blog/how-we-roll-passwords)
- [How We Roll – Chapter 2: Avatars](/blog/how-we-roll-avatars)
- [How We Roll – Chapter 3: Multifactor](/blog/how-we-roll-multifactor)
- [How We Roll – Chapter 4: Email Verification](/blog/how-we-roll-email-verification)
- [How We Roll – Chapter 5: Customization](/blog/how-we-roll-customization)
- [How We Roll – Chapter 6: User Profile](/blog/how-we-roll-user-profile)
- [How We Roll – Chapter 7: JWT Single Sign-On](/blog/how-we-roll-jwt-sso)
- [How We Roll – Chapter 8: Sessions](/blog/how-we-roll-sessions)
- [How We Roll – Chapter 9: Infrastructure](/blog/how-we-roll-infrastructure)
- *How We Roll – Chapter 10: Coming Soon!*

---

# Seamless Integration: How Clerk Streamlined OpusFlow's User Authentication
URL: https://clerk.com/blog/opusflow.md
Date: 2023-05-15
Category: Insights
Description: Learn how Clerk's user-friendly authentication system streamlined OpusFlow's SaaS integration, enhancing productivity and performance.

\_"We were blown away by the user-friendly authentication system that Clerk.com provides, allowing our SaaS to easily integrate with multiple teams of different skill levels. Not only did it offer MFA capabilities and organizations for a more efficient team, but its seamless integration into our tech stack resulted in an unbelievably productive experience! As CTO of OpusFlow, I'm extremely pleased with the 'just work' concept delivered via Clerk."

– **Joey Teunissen, CTO OpusFlow**\_

## About OpusFlow

[OpusFlow](https://opusflow.io) is the perfect ERP system for businesses dealing with installations, like solar panel systems, heat pumps and charging stations. OpusFlow's mission is to streamline efficiency within installation companies through automation of time-consuming processes. With this one-stop solution at your fingertips, you can rest assured that tedious manual tasks are no longer taking up precious hours in your day!

## **Tech Stack**

We have crafted an innovative tech stack to ensure the smooth operation of our platform. On the frontend, Next.js is utilized while PostgreSQL and Node.js run on a serverless system with Typescript and GraphQL compatibility. Hosting solutions are provided by Netlify in combination with AWS services for maximum performance and scalability.

Frontend: Next.js\
Backend: Node.js, Typescript, GraphQL, PostgreSQL, Serverless\
Hosting: Netlify, AWS

## **Before Clerk**

After many attempts at various authentication methods for our projects – from custom-made to Auth0 and others – OpusFlow soon realized the complexity that is often associated with these approaches. To simplify this process, we conducted extensive research until Clerk.com, a developer-friendly authentication platform, was discovered. After conducting a Proof of Concept test to ascertain its performance and reliability, Clerk became our obvious choice for internal projects. We quickly made the switch! Following the successful use of these projects, we decided to take it one step further and implemented Clerk into our largest enterprise SaaS ERP system yet.

## **After Clerk**

After using Clerk for an extended period, with numerous groups that consisted of anywhere from four to ten developers at a time, we are thrilled about the possibilities in store. It is already sufficient enough for our needs as it stands now and its support system provided by Clerk.com is remarkable – it's far more than mere assistance. The shared eagerness between both parties to continue progressing their platform further has been amazing!