Svenson
Svenson

Reputation: 133

How do I get an API access token dynamically for an NGINX proxy

I started to play around with the IGDB API for an iOS App. Some days ago IGDB launched V4 which now requires authorizing with Twitch via oAuth2 in order to receive an app access token.

With my poor backend knowledge (I literally started yesterday to learn about NGINX) I managed to set up an NGINX Webserver which proxies requests to the IGDB API and injects the app access token into the HTTP Header. This is working fine for now.

My proxy.conf which is included in the nginx.conf looks like this:

server {
    listen 443 ssl;
    server_name myhost.com;

    #SSL Config cut out  
    ...

    location / {
        proxy_pass https://api.igdb.com/v4/games;
        proxy_ssl_server_name on;
        proxy_set_header Client-ID "MY TWITCH APP CLIENT ID";
        proxy_set_header Authorization "Bearer THE_APP_ACCESS_TOKEN";
    }
}

However THE_APP_ACCESS_TOKEN was requested manually by me. For testing purposes this is fine, however it will expire after about 60 days (according to the Twitch Dev Docs). I am wondering now how I would dynamically request an access token (and store it somehow?), refresh it when it expires and inject it into the proxy.conf.

While researching I stumbled upon the HTTP Auth Request module in combination with the NGINX JavaScript module (https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/).

Now I wonder if it is a reasonable approach to trigger a token request via the Auth Request Module before proxying the request, parse the JSON response with the JavaScript Module and inject the app access token contained in the response as a variable into the HTTP header of the proxy. While this sounds good to me in theory I barely have an idea how to implement this. Moreover, this approach does not yet include storing and updating the token as soon as it expires.

Do you have some hints for me how to tackle this or is there even another solution?

Upvotes: 3

Views: 6754

Answers (1)

Svenson
Svenson

Reputation: 133

Okay, here's what I came up with. This seems to fit my use case:

  1. I wrote a shell script which makes a curl POST request to the twitch oAuth endpoint for getting an app access token and outputs the JSON response to a file (here: access.json)

    curl -o access.json -X POST 'https://id.twitch.tv/oauth2/token?client_id=<YOUR_CLIENT_ID>&client_secret=<YOUR_CLIENT_SECRET>&grant_type=client_credentials'

  2. After that, the script parses the value of the access_token key in the access.json with the jq command line tool and saves it to the variable newAccessToken. This is done with this line:

    newAccessToken=$(cat /<PATH_TO_JSON>/access.json | jq -r '.access_token')

    The cat command outputs the access.json and pipes it to the jq command which filters the json for the access_token key value.

  3. In the same directory of the script I placed a proxy_template.conf which consists all config information above but instead of the manually received access token it has the string "THEACCESSTOKEN".

  4. After storing the access_token key in the newAccessToken variable I search for the "THEACCESSTOKEN" string in the proxy_template.conf, replace it with the value of the newAccessToken variable and save the output in a new proxy.conf in the /etc/nginx/conf.d directory. This is done with the sed command:

    sed "s/THEACCESSTOKEN/$newAccessToken/g" /<PATH_TO_FILE>/proxy_template.conf > /nginx/etc/conf.d/proxy.conf

  5. In last line of the script I just nginx -s reload the server in order to use the new config file.

  6. In order to receive a fresh access token regularly I've set up a cron job which executes the shell script every day.

Not sure if this is the most elegant solution but it seems fine for my use case and works. If you have any other best practices I appreciate every hint. :)

Upvotes: 5

Related Questions