API Proxy - archcoder-jd/Fadeout GitHub Wiki

API Proxy

The problem

Anything in browser JavaScript can be read by visitors. Opening the browser's developer tools shows every request a page makes, including any API key inside it. Removing the key from the repo isn't enough if the browser still sends it to TMDB.

The solution

Fadeout never talks to TMDB from the browser. It talks to its own server, and the server talks to TMDB.

Browser  →  /api/tmdb/trending/movie/day  →  Node.js proxy  →  TMDB
                                             (adds the key)

How a request flows

  1. The front end requests data from its own domain, for example /api/tmdb/movie/603?language=en-US. In the code, BASE_URL is set to /api/tmdb/.
  2. server/app.js receives it and:
    • accepts only GET requests
    • removes any api_key the browser sent
    • checks the path against an allow-list
  3. It forwards the request to https://api.themoviedb.org/3/... with the key in an Authorization: Bearer header.
  4. It returns TMDB's response to the browser unchanged.

Where the key lives

The key is stored in the TMDB_TOKEN environment variable:

  • On the server: set in cPanel's Node.js app manager
  • On your computer: in a .env file, which .gitignore keeps out of the repo

The repository only ever contains the variable's name, never the key.

The allow-list

Only these TMDB sections can be requested through the proxy:

/movie, /tv, /search, /trending, /genre, /discover, /person, /configuration

Anything else gets {"error":"Not allowed"}. This stops other people from using the proxy as free access to the rest of TMDB's API on Fadeout's quota. Paths containing .. are also rejected.

Which token to use

Use the API Read Access Token from your TMDB account (Settings → API), the long one starting with eyJ. The shorter API Key doesn't work with a Bearer header and returns Invalid API key.

Adding another API

The same pattern will protect the AI features on the Roadmap: a new environment variable for the key, and a new route in the proxy. The key never goes in the front-end code.