Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(express) update quickstart and overview #1899

Merged
merged 3 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 30 additions & 14 deletions docs/quickstarts/express.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ description: Learn how to use Clerk to quickly and easily add secure authenticat
- Protect your routes using `requireAuth()`
</TutorialHero>

Learn how to integrate Clerk into your Express backend for secure user authentication and management. This guide covers backend implementation only and requires a Clerk frontend SDK in order for any of this to work.
Learn how to integrate Clerk into your Express backend for secure user authentication and management. This guide focuses on backend implementation and requires a Clerk frontend SDK to function correctly.

<Steps>
## Install `@clerk/express`

Clerk's [Express SDK](/docs/references/express/overview) ships with a variety of helpers for the backend to make user authentication easier.
Clerk's [Express SDK](/docs/references/express/overview) gives you access to prebuilt components, React hooks, and helpers to make user authentication easier.

To get started using Clerk with Express, add the SDK to your project:
Run the following command to install the SDK:

<CodeBlockTabs options={["npm", "yarn", "pnpm"]}>
```bash {{ filename: 'terminal' }}
Expand Down Expand Up @@ -88,7 +88,7 @@ Learn how to integrate Clerk into your Express backend for secure user authentic
```
</CodeBlockTabs>

## Add `clerkMiddleware()` to your application
## Add `clerkMiddleware()` to your app

The [`clerkMiddleware()`](/docs/references/express/overview#clerk-middleware) function checks the request's cookies and headers for a session JWT and, if found, attaches the [`Auth`](/docs/references/backend/types/auth-object#auth-object){{ target: '_blank' }} object to the `request` object under the `auth` key.

Expand All @@ -98,10 +98,12 @@ Learn how to integrate Clerk into your Express backend for secure user authentic
import { clerkMiddleware } from '@clerk/express'

const app = express()
const PORT = 3000

app.use(clerkMiddleware())

app.listen(3000, () => {
// Start the server and listen on the specified port
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
```
Expand All @@ -110,30 +112,44 @@ Learn how to integrate Clerk into your Express backend for secure user authentic

To protect your routes, use the [`requireAuth()`](/docs/references/express/overview#require-auth) middleware. This middleware functions similarly to `clerkMiddleware()`, but also protects your routes by redirecting unauthenticated users to the sign-in page.

In the following example, `requireAuth()` is used to protect the `/protected` route. If the user is not authenticated, they are redirected to the '/sign-in' route. If the user is authenticated, the `req.auth` object is used to get the `userId`, which is passed to [`clerkClient.users.getUser()`](/docs/references/backend/user/get-user){{ target: '_blank' }} to fetch the current user's `User` object.
In the following example, `requireAuth()` is used to protect the `/protected` route. If the user isn't authenticated, they're redirected to the homepage. If the user is authenticated, the [`getAuth()`](/docs/references/express/overview#get-auth) function is used to get the `userId`, which is passed to [`clerkClient.users.getUser()`](/docs/references/backend/user/get-user){{ target: '_blank' }} to fetch the current user's `User` object.

```ts {{ filename: 'index.ts', mark: [3, [7, 11], [13, 16]] }}
import 'dotenv/config'
import express from 'express'
import { clerkClient, requireAuth } from '@clerk/express'

const app = express()
const PORT = 3000

app.get('/protected', requireAuth({ signInUrl: '/sign-in' }), async (req, res) => {
const { userId } = req.auth
// Use requireAuth() to protect this route
// If user isn't authenticated, requireAuth() will redirect back to the homepage
app.get('/protected', requireAuth(), async (req, res) => {
// Use `getAuth()` to get the user's `userId`
const { userId } = getAuth(req)

// Use Clerk's JavaScript Backend SDK to get the user's User object
const user = await clerkClient.users.getUser(userId)
return res.json({ user })
})

app.get('/sign-in', (req, res) => {
// Assuming you have a template engine installed and are using a Clerk JavaScript SDK on this page
res.render('sign-in')
return res.json({ user })
})

app.listen(3000, () => {
// Start the server and listen on the specified port
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
```

## Add global TypeScript type (optional)

If you're using TypeScript, add a global type reference to your project to enable auto-completion and type checking for the `auth` object in Express request handlers.

1. In your application's root folder, create a `types/` directory.
1. Inside this directory, create a `globals.d.ts` file with the following code.

```ts {{ filename: 'types/globals.d.ts' }}
/// <reference types="@clerk/express/env" />
```
</Steps>

## Next steps
Expand Down
39 changes: 23 additions & 16 deletions docs/references/express/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ title: Clerk Express SDK
description: Learn how to integrate Clerk into your Express application using the Clerk Express SDK.
---

The Clerk Express SDK is the recommended method for integrating Clerk into your Express application.

See the [quickstart](/docs/quickstarts/express) to get started.
The Clerk Express SDK is the recommended method for integrating Clerk into your Express application. Refer to the [quickstart](/docs/quickstarts/express) to get started.

{/* TODO: Remove callout when Node SDK is removed from docs */}

Expand Down Expand Up @@ -57,13 +55,16 @@ The `clerkMiddleware()` function accepts [these options](https://clerk.com/docs/

### `requireAuth()`

The `requireAuth()` middleware functions similarly to `clerkMiddleware()`, but also protects your routes by redirecting unauthenticated users to the sign-in page. It will look for a `CLERK_SIGN_IN_URL` environment variable and use that by default. If not present, you must pass a sign in URL to the middleware as an option.
The `requireAuth()` middleware functions similarly to `clerkMiddleware()`, but also protects your routes by redirecting unauthenticated users to the homepage. It accepts the same [options](/docs/references/express/overview#options) as `clerkMiddleware()`.

You can also specify a custom sign-in URL to redirect unauthenticated users to by setting the `CLERK_SIGN_IN_URL` environment variable or by passing a `signInUrl` option to the middleware. It's recommended to set the environment variable.

```js
import { requireAuth } from '@clerk/express'
import express from 'express'

const app = express()
const PORT = 3000

// Apply middleware to all routes
app.use(requireAuth())
Expand All @@ -77,13 +78,16 @@ app.get('/protected', requireAuth(), (req, res) => {
app.get('/protected', requireAuth({ signInUrl: '/sign-in' }), (req, res) => {
res.send('This is a protected route')
})
```

This middleware accepts the same [options](/docs/references/express/overview#options) as `clerkMiddleware()`.
// Start the server and listen on the specified port
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`)
})
```

### `getAuth()`

The `getAuth()` helper retrieves authentication state from the request object. See the [Next.js reference documentation](https://clerk.com/docs/references/nextjs/get-auth) for more information on how to use the returned `auth` object.
The `getAuth()` helper retrieves authentication state from the request object. See the [Next.js reference documentation](https://clerk.com/docs/references/nextjs/get-auth) for more examples on how to use the returned `auth` object.

The following example uses `requireAuth()` to protect the route based on _authentication_ status, and then uses `getAuth()` to protect the route based on _authorization_ status.

Expand All @@ -92,12 +96,12 @@ import { clerkMiddleware, getAuth, requireAuth } from '@clerk/express'
import express from 'express'

const app = express()
const port = 3000
const PORT = 3000

// Apply centralized middleware
app.use(clerkMiddleware())

// Protect a route based on authorization status
// Use `getAuth()` to protect a route based on authorization status
const hasPermission = (req, res, next) => {
const auth = getAuth(req)

Expand All @@ -109,28 +113,30 @@ const hasPermission = (req, res, next) => {
return next()
}

// Use `requireAuth()` to protect this route
// If user is not authenticated, requireAuth() will redirect back to the homepage
app.get('/path', requireAuth(), hasPermission, (req, res) => res.json(req.auth))

// Start the server and listen on the specified port
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`)
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`)
})
```

### `clerkClient`

[Clerk's JavaScript Backend SDK](/docs/references/backend/overview) exposes the Backend API resources and low-level authentication utilities for JavaScript environments. For example, if you wanted to get a list of all users in your application, instead of creating a fetch to the `https://api.clerk.com/v1/users` endpoint, you can use the `users.getUserList()` method provided by the JavaScript Backend SDK.

All resource operations are mounted as sub-APIs on the `clerkClient` object. See the [reference documentation](/docs/references/backend/overview#usage) for more information.
All resource operations are mounted as sub-APIs on the `clerkClient` object. See the [reference documentation](/docs/references/backend/overview#usage){{ target: '_blank' }} for more information.

```js
import { clerkClient, requireAuth } from '@clerk/express'
import express from 'express'

const app = express()
const port = 3000
const PORT = 3000

app.get('/users', async (req, res) => {
app.get('/user', async (req, res) => {
// Get the `userId` from the `Auth` object
const userId = req.auth.userId

Expand All @@ -140,11 +146,12 @@ app.get('/users', async (req, res) => {

// Use the userId to get information about the user
const user = await clerkClient.users.getUser(userId)

return void res.status(200).json(user)
})

// Start the server and listen on the specified port
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`)
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`)
})
```
Loading