Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jwhm's avatar
Level 1

Nuxt, getting external API through proxy correctly

So I have a SSR Nuxt JS app that communicates with a variety of different API from different providers, all with different authentication methods.

Some providers require a x-auth-email header to be sent, which is fine I have been using interceptors to add the header values in, this works fine and all the API work.

My concern is that, the initial load hides the request and renders the page, however obviously if a user navigates away and back to that page via a nuxt-link, you can find the request in the network tab, view the headers, and see the private API key, or email that has to be included.

Is there anyway to make Nuxt JS completely SSR, so those requests are never seen by the user, because obviously the user could grab the bearer token, and annoyingly some of these providers don't allow you to have only accept requests from specific IP(s) or CORS.

The user could also see the secret x-auth-email header values which can then be used in postman in combination to grab data they shouldn't have access to, obviously not a good idea. Honestly, I think I would've been better building this in Laravel, but here we are in Nuxt JS.

My question boils down to, is it possible to render all requests on the server, regardless of user navigation, or to encrypt those header values so that the user's browser cannot see the unencrypted headers value in the request?

A example of my current setup:

/*
* Axios is required for this plugin to work
*/
import axios from 'axios'

export default function ({ 
    /*
    * Extend Axios into the plugin
    */
    $axios, 
    
    /*
    * Get relevant config variables
    */    
    $config: {
        CF_ACCESS_CLIENT_ID, 
        CF_ACCESS_CLIENT_SECRET, 
    }
    
    }){

    /*
    * When the request is made, add the token to the header
    */
    $axios.onRequest((config) => {
        /*
        * Only run on the server
        */
        if (!process.server) {
            return
        }

        /*
        * Try to get the token
        */
        try {
            /*
            * Match regex to only graphql requessts
            */
            const enhUrlRegex = /^\/api\/graphql\/(.*)$/

            /*
            * If the request is for graphql, add the token to the header
            */
            if (enhUrlRegex.test(config.url)) {
                config.headers.cf_access_client_id = `${CF_ACCESS_CLIENT_ID}`
                config.headers.cf_access_client_secret = `${CF_ACCESS_CLIENT_SECRET}`
            }
            
        } catch (error) {
            console.log(error)
        }        
    })
}  
  proxy: {
    "/api/graphql": {
        "target": "https://api.domain.io/graphql/",
        "secure": true,
        "changeOrigin": true,
        "pathRewrite": {
          "^/api/graphql": '',
        }
    },            
  },
0 likes
1 reply
bhuvidya's avatar

Instead of adding the headers in $axios.onRequest(), maybe all you need to do is add the headers as part of the proxy config, like this:

proxy: {
  "/api/graphql": {
    ...
    headers: {
      "cf_access_client_id": process.env.CF_ACCESS_CLIENT_ID,
      "cf_access_client_secret": process.env.CF_ACCESS_CLIENT_SECRET,
    },
  }
}

None of this proxy config is seen in the client browser as the proxy logic is performed server-side. I use this approach myself to proxy to several different backend APIs and it works well (NuxtJS v2.15). The Nuxt Proxy module leans on http-proxy-middleware, and you can see it's available options here https://github.com/chimurai/http-proxy-middleware#options.

Something else you might find handy is how to adjust the request in a more "dynamic" way. For instance, if you had to add a secret code as a GET param to the request, or add an auth token that can only be determined at runtime (e.g. via a cookie), you could do something like the following:

proxy: {
  "/api/graphql": {
    ...
    onProxyReq: (proxyReq, req, res) => {
      const code = process.env.API_CODE;
      if (code) {
        proxyReq.path += `${proxyReq.path.indexOf('?') !== -1 ? '&' : '?'}code=${encodeURIComponent(code)}`;
      }

      // add auth token??
      const authToken = ...;
      proxyReq.setHeader('Authorisation', `Bearer ${authToken}`);
    },
  },
}

Please or to participate in this conversation.