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

Sve*_*son 2 api backend nginx nginx-reverse-proxy twitch-api

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

凭借我糟糕的后端知识(我昨天开始学习 NGINX),我设法设置了一个 NGINX Web 服务器,它代理对 IGDB API 的请求并将应用程序访问令牌注入到 HTTP 标头中。目前这工作正常。

我的 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";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

您对我如何解决这个问题有一些提示吗?或者还有其他解决方案吗?

Sve*_*son 5

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

  1. 我编写了一个 shell 脚本,它curl向 twitch oAuth 端点发出 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. 之后,脚本access_token使用命令行工具解析access.json中key的值jq并将其保存到变量中newAccessToken。这是通过这一行完成的:

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

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

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

  4. 将密钥存储access_tokennewAccessToken变量中后,我在 proxy_template.conf 中搜索“THEAACCESSTOKEN”字符串,将其替换为 newAccessToken 变量的值,并将输出保存在目录中的新目录proxy.conf/etc/nginx/conf.d。这是通过以下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 作业。

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