Using Cloudflare Workers as a Proxy for Firebase Authentication
Tags: javascript, webdev, firebase, cloudflare
Published: 2023-04-02 10:43:38

## Setting Up Cloudflare Workers

Firebase is a popular platform for building web and mobile applications. One of the most commonly used authentication methods in Firebase is `signInWithRedirect`. However, there is a known issue with this function on Safari browsers where cross-domain cookies do not work. This means that the authentication cannot be done in the Firebase project's URL, which will be something like `myapp-123asdf.firebaseapp.com/`, and we have to serve the authentication handlers ourselves. 

To resolve this issue, we can use Cloudflare Workers as a proxy for Firebase authentication, so we can serve the authentication on the same domain as our application. This way, we can set the cookies for e.g. `app.example.com` and use it in the application after the redirect. This will allow any user to authenticate with the `signInWithRedirect` function. In this blog post, I will guide you through the process of setting up Cloudflare Workers for Firebase authentication.

Note that this guide requires that you maintain your DNS records with Cloudflare already. As we will register a serverless function running on the same domain as your application, Cloudflare needs to be able to register a new record pointing to your function.

### Register a Cloudflare Worker

The first step is to register a Cloudflare Worker. If you don't already have a Cloudflare account, you will need to create one and add your domain to it, so that we can register a route for the domain later on. Once you have logged in to your Cloudflare account, click on the Workers section in the sidebar.

![Creating a Cloudflare Worker to proxy requests to Firebase Authentication](https://lakur.tech/2023/04/create-worker.png "Creating a Cloudflare Worker to proxy requests to Firebase Authentication")

Next, you should give the worker a good name so that it is easy recognizable. You can pick any of the code examples.

![Naming a Cloudflare Worker to proxy requests to Firebase Authentication](https://lakur.tech/2023/04/name-worker.png "Name your worker so you will recognize it in the future.")

Confirm the Creation and you will be greeted with an overview of the just created service. By clicking "Quick Edit" we can jump straight into a code editor for the Worker and start implementing necessary logic to proxy the requests to Firebase Authentication.

### Implementing the Worker to proxy requests to Firebase Authentication

To implement the actual code that proxies requests from our `app.example.com` domain (where your application is running) to the external Firebase Authentication system, we will define some logic for our Worker using JavaScript. The first step is to define the project URL of your Firebase project. It is in the format `https://project-id.firebaseapp.com`. Your project ID can be found in the Firebase console under Project settings > General > Project ID.

If your project ID would be `myapp-1dg8y9`, your project URL would be `https://myapp-1dg8y9.firebaseapp.com` 

Define your project URL as `firebaseProjectUrl`:
```javascript
const firebaseProjectUrl = 'https://myapp-1dg8y9.firebaseapp.com';
```

We can then define the Cloudflare Worker to listen for requests on `/__/auth/` and proxy them to the Firebase authentication URL.

```javascript
const firebaseProjectUrl = 'https://myapp-1dg8y9.firebaseapp.com';

export default {
  async fetch(request) {
    const requestUrl = new URL(request.url);
    if (requestUrl.pathname.startsWith("/__/auth/")) {
      const transformedUrl = new URL(
        firebaseProjectUrl + requestUrl.pathname + requestUrl.search
      );
      const newRequest = new Request(transformedUrl.toString(), {
        method: request.method,
        headers: request.headers,
      });
      return fetch(newRequest);
    }
    return new Response("Not found", { status: 404 });
  },
};

```

This code listens for requests on `/__/auth/` and rewrites the request to be directed to your Firebase project URL. Then, it creates a new request object with the rewritten URL and forwards the original request's headers and method. Finally, it returns the response from Firebase.

With this code, we have successfully set up a Cloudflare Worker to proxy our app's Firebase authentication requests. In the next section, we will guide you through the process of setting up the routing for this Worker.

### Configure the Cloudflare Worker
Now that we have created a new Worker, we need to configure it to be reachable under our app's domain, so that it can rewrite requests to Firebase Authentication for us.

First, go to your Cloudflare dashboard and navigate to the Workers section. Click on the worker you just created to open its settings page. There, select Triggers to configure the Worker's triggers.

![Configure the trigger so a request to your app domain gets proxied to Firebase Authentication](https://lakur.tech/2023/04/worker-configure-triggers.png "Configure the trigger so a request to your app domain gets proxied to Firebase Authentication")
Under the "Routes" section, click "Add route" to add a new route with the Route `app.example.com/__/auth/*`, where you . This tells Cloudflare to use the Cloudflare Worker for any requests that start with `/__/auth/`. 
Then select the fitting Zone / Domain for your worker.
![Configure the route for your Cloudflare Worker request proxy](https://lakur.tech/2023/04/add-route-to-worker.png "Configure the route for your Cloudflare Worker request proxy")

That was the Cloudflare part, nice!

## Setting Up Your App
### Registering the new authorized domain in Firebase Authentication
Next, we need to add the app's domain (`app.example.com`) to our Firebase project's Authorized domains. Go to the Firebase console and navigate to Authentication > Settings. Under Authorized domains, add your app's domain + `/__/auth/handle`, so for our `app.example.com` application you would add `https://app.example.com/__/auth/handle`. The Firebase Settings UI does not show the pathname entered here, but it matters, so be sure to add it this way.

### Changing your firebase configuration
Finally, we need to update our Firebase configuration to use the new authentication domain. In your app's Firebase configuration, update the `authDomain` property to use your Cloudflare worker domain.

```javascript
const firebaseConfig = {
  // [...]
  authDomain: 'app.example.com'
};
```

With these configurations, we have successfully set up our Cloudflare Worker to proxy Firebase authentication requests and configured our Firebase project to use the new authentication domain. In the next section, we will guide you through the process of testing this setup.

## Testing
To test if your setup is working as expected, you can navigate to `https://app.example.com/__/auth/handle`. If you see a "Site Not Found" Firebase error, your project was configured correctly, as the default action for GET requests to the auth handle is what's currently displayed. You can deploy your change now, the sign in will work under Safari now!

## Conclusion

By using Cloudflare Workers as a proxy for Firebase authentication, we can ensure that any user can authenticate with the `signInWithRedirect` function. The process involves registering a Cloudflare Worker and configuring it to resolve the requests as a proxy, configuring your Firebase project to allow the authentication domain, configuring your application, and then testing the Cloudflare Worker and Firebase authentication to ensure this works before deploying.