Search code examples
cloudflarecloudflare-workers

Cloudflare Worker Service needs an access token


I created a Worker Service https://bla-bla-bla.hi.workers.dev as shown here https://blog.cloudflare.com/sending-email-from-workers-with-mailchannels which sends mail I want to call this endpoint from my backend, but right now anyone can call it

How to make it so that only I can call it? And it's okay if I hardcode some token and call it https://bla-bla-bla.hi.workers.dev/ with the token?

Thanks


Solution

  • Usually third party services (such as mailchannels) support authentication tokens. If so, you could modify the code of your worker so that it receives the authorization token in a request parameter, and forwards it to the third party service. Then change your backend to make the call using the token.

    If the third party service does not support authentication mechanisms, you could implement one in your Worker. A very simple method is checking for a pre-shared secret (that your backend can send in the request). An example is available here (and reported below for simplicity)

    An additional note is that it's not advisable to hardcode secrets directly in the code. Best to use an environment variable (specifically a secret) to store it and read it to do the comparison in the code.

    /**
     * @param {string} PRESHARED_AUTH_HEADER_KEY Custom header to check for key
     * @param {string} PRESHARED_AUTH_HEADER_VALUE Hard coded key value
     */
    const PRESHARED_AUTH_HEADER_KEY = 'X-Custom-PSK';
    const PRESHARED_AUTH_HEADER_VALUE = 'mypresharedkey';
    
    async function handleRequest(request) {
      const psk = request.headers.get(PRESHARED_AUTH_HEADER_KEY);
    
      if (psk === PRESHARED_AUTH_HEADER_VALUE) {
        // Correct preshared header key supplied. Fetch request from origin.
        return fetch(request);
      }
    
      // Incorrect key supplied. Reject the request.
      return new Response('Sorry, you have supplied an invalid key.', {
        status: 403,
      });
    }
    
    addEventListener('fetch', event => {
      event.respondWith(handleRequest(event.request));
    });