---
updatedAt: 2026-08-20T17:47:54.000Z
agentTools:
  projectIndex: https://docs.wristband.dev/llms.txt
---

# Protect Backend Endpoints

Learn to protect your API endpoints with Wristband's authentication middleware.

Utilize the `requireWristbandAuth` middleware, created during the initial setup, to restrict endpoint access exclusively to authenticated users. This section details how to apply the <Anchor target="_blank" href="https://docs.wristband.dev/docs/expressjs-add-auth-middleware">middleware</Anchor> to protect private API endpoints.

## Using the Auth Dependency to Protect Endpoints

Secure your endpoint from unauthenticated access by adding the `requireWristbandAuth` middleware:

```python Protected Endpoint
# src/routes/protected_routes.py
from fastapi import APIRouter, Depends, Response, status
from auth.wristband import require_session_auth

router = APIRouter()

# Use the require_session_auth dependency in your dependencies list to verify that 
# incoming requests have a valid session.
@router.get("/protected-api", dependencies=[Depends(require_session_auth)])
async def protected_api() -> Response:
    return { "message": "This is a protected endpoint" }
```

If an unauthenticated user attempts to access this API, the server will return a `401 Unauthorized` status.

## Handling 401 Responses in Frontend Code

If your frontend requests an endpoint protected by `requireWristbandAuth` without a valid session, the server will return this error response:

* `401 Unauthorized`:  This response will be returned if the session is missing or invalid.

To ensure a smooth user experience, your frontend must handle this error properly. Below are the most common patterns for managing 401 errors in JavaScript.

### Pattern 1: Use an Axios Interceptor

Implement an Axios response interceptor to manage `401 Unauthorized` states. This example redirects the user to the login endpoint whenever a 401 response occurs.

```typescript Axios
// api-client.ts
import axios from 'axios';
import { redirectToLogin } from '@wristband/react-client-auth';

const apiClient = axios.create({
  baseURL: '<backend-apis-base-url>',
  headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
  withCredentials: true,
});

// If a 401 response is detected, redirect the user to your Login Endpoint.
const unauthorizedAccessInterceptor = (error: unknown) => {
  if (axios.isAxiosError(error) && error.response?.status === 401) {
    redirectToLogin('<your-login-endpoint-url>');
    return;
  }
  return Promise.reject(error);
};

apiClient.interceptors.response.use(undefined, unauthorizedAccessInterceptor);

export { apiClient };

```

### Pattern 2: Explicitly Catch Errors When Making API Calls

Explicitly catching errors during individual API calls provides greater precision. This enables you to deploy unique error-handling logic for each endpoint rather than relying on a global handler.

```typescript Axios
import axios from 'axios';
import { redirectToLogin } from '@wristband/react-client-auth';

async function executeApiCall() {
  try {
    const response = await axios.get('<your-server-api-url>');
    alert('Success!');
  } catch (error: unknown) {
    if (axios.isAxiosError(error) && error.response?.status === 401) {
      redirectToLogin('<your-login-endpoint-url>');
    } else {
      console.error('Unexpected error:', error);
      alert('Something went wrong!');
    }
  }
}

```
```typescript Fetch
import { redirectToLogin } from '@wristband/react-client-auth';

function getCookie(name: string): string | null {
  const match = document.cookie.match(new RegExp('(^|;\\s*)' + name + '=([^;]*)'));
  return match ? decodeURIComponent(match[2]) : null;
}

async function executeApiCall() {
  const csrfToken = getCookie('CSRF-TOKEN');

  try {
    const response = await fetch('/api/protected-endpoint', {
      credentials: 'include',
      headers: {
        'X-CSRF-TOKEN': csrfToken ?? ''
      }
    });

    if (!response.ok) {
      if (response.status === 401 || response.status === 403) {
        redirectToLogin('<your-login-endpoint-url>');
        return;
      }

      const errorText = await response.text();
      throw new Error(`HTTP error! status: ${response.status}, Message: ${errorText}`);
    }

    ...
  } catch (error) {
    ...
  }
}
```

<HTMLBlock>{`
<style>
.UpdatedAt {
  display: none;
}
</style>
`}</HTMLBlock>