Heroku not passing x-rapidapi-proxy-secret header to API

I’m having trouble with my RapidAPI-listed API on Heroku. The x-rapidapi-proxy-secret header isn’t reaching my API after Heroku’s redirect.

Here’s what’s happening:

  1. A request arrives at Heroku with the secret header
  2. Heroku forwards the request to a dyno
  3. The forwarded request loses the secret header
  4. My API rejects the request because the header is missing

I’ve implemented middleware to check for the header:

@app.middleware("http")
async def verify_rapidapi_secret(request: Request, call_next):
    if os.getenv("API_SECRET"):
        if request.headers.get("X-RapidAPI-Proxy-Secret") != os.getenv("API_SECRET"):
            return PlainTextResponse("Access denied", status_code=403)
    return await call_next(request)

How can I resolve this? Should I update my header check approach, or is there a way to ensure Heroku forwards the header?

I’ve dealt with similar issues when deploying APIs on Heroku. One effective solution I found was to use the X-Forwarded-For header instead of X-RapidAPI-Proxy-Secret. Heroku typically preserves this header, and you can use it to verify the request origin.

Here’s a snippet I’ve used successfully:

@app.middleware("http")
async def verify_request_origin(request: Request, call_next):
    forwarded_for = request.headers.get("X-Forwarded-For")
    if forwarded_for and forwarded_for.split(',')[0] in ALLOWED_IPS:
        return await call_next(request)
    return PlainTextResponse("Access denied", status_code=403)

You’ll need to maintain a list of RapidAPI’s IP addresses (ALLOWED_IPS) and update it periodically. This approach has been more reliable for me than relying on the proxy secret header.

Also, double-check your Heroku config vars to ensure the API_SECRET is set correctly. Sometimes, it’s a simple oversight that causes these issues.

hey, i’ve run into this too. heroku can be a pain with headers sometimes. have you tried using the X-Forwarded-For header instead? it usually sticks around after redirects. you could check if it matches RapidAPI’s IP range. might be worth a shot if nothing else is working for ya.

Having worked with Heroku and RapidAPI, I can suggest a workaround. Instead of relying solely on the x-rapidapi-proxy-secret header, consider implementing a two-step verification process. First, check for the presence of RapidAPI-specific headers like x-rapidapi-host and x-rapidapi-key. These are usually preserved. Then, as an additional security measure, validate the request’s origin IP against a whitelist of RapidAPI’s known IP ranges.

Here’s a simplified example:

@app.middleware("http")
async def verify_rapidapi_request(request: Request, call_next):
    if (request.headers.get("x-rapidapi-host") and
        request.headers.get("x-rapidapi-key") and
        request.client.host in RAPIDAPI_IP_RANGES):
        return await call_next(request)
    return PlainTextResponse("Unauthorized", status_code=401)

This approach has proven more reliable in my experience, as it doesn’t depend on a single header that Heroku might strip. Remember to keep your RAPIDAPI_IP_RANGES list updated regularly for optimal security.