如何为 NGINX 代理动态获取 API 访问令牌

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

我开始使用 IGDB API 作为 iOS 应用程序。几天前,IGDB 推出了 V4,现在需要通过 oAuth2 向 Twitch 授权才能接收应用程序访问令牌。

由于我对后端的了解很少(我昨天才真正开始了解 NGINX),我设法设置了一个 NGINX Web 服务器,它代理对 IGDB 的请求 API 并将应用程序访问令牌注入 HTTP Header。目前一切正常。

我的 proxy.conf 包含在 nginx.conf 中,如下所示:

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";
    }
}

然而 THE_APP_ACCESS_TOKEN 是我手动请求的。出于测试目的,这很好,但它会在大约 60 天后过期(根据 Twitch 开发文档)。我现在想知道如何动态请求访问令牌(并以某种方式存储它?),在它过期时刷新它并将其注入 proxy.conf.

在研究过程中,我偶然发现了 HTTP 身份验证请求模块与 NGINX JavaScript 模块 (https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/) 的结合。

现在我想知道在代理请求之前通过授权请求模块触发令牌请求是否是一种合理的方法,使用 JavaScript 模块解析 JSON 响应并注入应用程序访问权限响应中包含的令牌作为代理的 HTTP header 中的变量。虽然这在理论上对我来说听起来不错,但我几乎不知道如何实现它。此外,这种方法还不包括令牌过期后立即存储和更新令牌。

你能给我一些解决这个问题的提示吗?或者还有其他解决方案吗?

好的,这就是我的想法。这似乎适合我的用例:

  1. 我写了一个 shell 脚本,它向 twitch oAuth 端点发出 curl POST 请求以获取应用程序访问令牌并输出 JSON 对文件的响应(此处: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. 之后,脚本用jq命令行工具解析access.json中access_token键的值,并保存到变量newAccessToken。这是通过以下行完成的:

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

    cat 命令输出 access.json 并将其通过管道传递给 jq 命令 过滤 access_token 键值的 json。

  3. 在脚本的同一目录中,我放置了一个 proxy_template.conf,其中包含上面的所有配置信息,但它不是手动接收的访问令牌,而是字符串“THEACCESSTOKEN”。

  4. newAccessToken 变量中存储 access_token 键后,我在 proxy_template.conf 中搜索“THEACCESSTOKEN”字符串,将其替换为newAccessToken 变量并将输出保存在 /etc/nginx/conf.d 目录中的新 proxy.conf 中。这是通过 sed 命令完成的:

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

  5. 在脚本的最后一行,我只是 nginx -s reload 服务器以便使用新的配置文件。

  6. 为了定期接收新的访问令牌,我设置了一个每天执行 shell 脚本的 cron 作业。

不确定这是否是最优雅的解决方案,但它似乎适合我的用例并且可以正常工作。如果您有任何其他最佳实践,我很感激每一个提示。 :)