# OAuth2 for Backend-for-Frontend

Most OAuth2 implementations and guides focus on **SPAs and mobile apps**, where the frontend directly handles tokens. While this approach is common, it introduces security concerns and additional complexity.

For **Remix & React Router applications**, a **Backend-for-Frontend (BFF) architecture** provides a more secure and controlled approach to authentication and API access.

## What is a Backend-for-Frontend (BFF)?

A **BFF** is a small server that sits between the frontend and external APIs. Instead of handling **OAuth2 tokens** in the browser, the BFF takes care of authentication and API requests. This approach offers several advantages:

- **Manages authentication server-side**
- **Stores tokens securely**
- **Handles API requests on behalf of the frontend**

## Why Use a BFF with OAuth2?

Handling OAuth2 in the **browser** often leads to issues such as:

- **Storing tokens in localStorage/sessionStorage** → Exposes them to **XSS attacks**.
- **Dealing with CORS issues** → When making direct API calls from the frontend.
- **Complexity in token refresh & expiration** → Managing tokens in the browser requires additional handling for refresh flows.

By using a **BFF**, the frontend **never directly interacts with OAuth2 tokens**. This **improves security** and **simplifies authentication flows**.

## How Authentication Works in a BFF Architecture

With a BFF, authentication follows these steps:

1. The user logs in via the BFF.
2. The BFF obtains and **securely stores tokens**.
3. The frontend makes **requests to the BFF**, not directly to external APIs.
4. The BFF **forwards requests** to the API, attaching the necessary tokens.

Since the **BFF handles authentication**, it must store tokens securely.

- **Access Token**: Short-lived, can be stored in memory.
- **Refresh Token**: Stored in a secure session (e.g., HTTP-only cookies).

This approach allows the **backend** to handle token refresh automatically, reducing complexity on the frontend.

## Secure Token Refresh in a BFF

Instead of exposing the **refresh token** to the frontend, the BFF follows this process:

1. The frontend makes a request to the BFF.
2. The BFF **checks if the access token is valid**.
3. If expired, it **uses the refresh token** to obtain a new one.
4. The BFF sends the **updated response** back to the frontend.

With this setup, **no tokens ever touch the browser**, ensuring a much safer authentication flow.

## Example: Authenticating Requests via a BFF in Remix

In a **Remix or React Router** application, a loader function can authenticate requests using the BFF:

```ts
export async function loader({ request }: Route.LoaderArgs) {
  let session = await getSession(request.headers.get("cookie"));
  let accessToken = await refreshToken(session.get("refreshToken"));
  let response = await fetch(new URL("/user", API_BASE_URL), {
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  return data({ user: UserSchema.promise().parse(response.json()) });
}
```

By keeping **OAuth2 tokens off the frontend**, this architecture enhances security and **simplifies authentication logic**.

## Why OAuth2 and BFF Work Well Together

A **BFF architecture** pairs well with **OAuth2** in **Remix & React Router apps** because it:

✅ **Prevents tokens from being exposed on the frontend**  
✅ **Centralizes authentication logic**  
✅ **Simplifies secure API access**  
✅ **Handles token refresh seamlessly**  

If you're building a **web application with OAuth2**, this is an approach worth considering. It strikes a balance between **security, flexibility, and ease of implementation**.

---

Want to master secure OAuth2 flows in React Router apps?

📘 My book *React Router OAuth2 Handbook* is now available!

It covers everything from the basics to advanced topics like PKCE, refresh tokens, and E2E auth testing.

→ [books.sergiodxa.com/release](https://go.sergiodxa.com/x6EE88z)