You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx日志字段替换为SHA-512哈希:njs异步函数适配方案咨询

解决Nginx日志字段SHA-512哈希的njs同步实现

Nginx的js_set确实不支持异步函数——它要求同步返回结果,所以你用async函数的话,返回的Promise对象会被直接转成字符串[object Promise],这就是你看到的问题。

其实njs本身提供了同步的SHA-512哈希接口,不用依赖异步的crypto.subtle.digest,刚好适配js_set的同步要求。

配置示例

nginx.conf的http段

js_import obfuscate.js;
js_set $obfuscated_token obfuscate.get_obfuscated_token;
log_format  main escape=json '{'
'"http_authorization":"$obfuscated_token",'
'}';

server {
    listen 80;
    access_log /var/log/nginx/access.log main;
    # 其他业务配置...
}

obfuscate.js代码

function get_obfuscated_token(r) {
    // 获取原始Authorization字段,为空时设默认值避免报错
    const rawToken = r.headersIn['Authorization'] || '';
    // 同步创建SHA-512哈希对象并计算
    const hash = crypto.createHash('sha512');
    hash.update(rawToken);
    // 返回十六进制格式的哈希结果
    return hash.digest('hex');
}

核心原因

njs的crypto.createHash是同步API,完全符合js_set对同步返回值的要求,不需要异步操作,也不用引入第三方模块,完美避开你担心的维护和许可证问题。


Lua方案(OpenResty环境)

如果你的环境是OpenResty,也可以用内置模块实现同步SHA-512哈希:

nginx.conf的http段配置

lua_shared_dict dummy 1m; # OpenResty要求必须定义共享字典才能启用部分模块
log_format  main escape=json '{'
'"http_authorization":"$obfuscated_token",'
'}';

server {
    listen 80;
    access_log /var/log/nginx/access.log main;

    set $obfuscated_token '';
    access_by_lua_block {
        local raw_token = ngx.req.get_headers()['Authorization'] or ''
        -- 计算二进制哈希值
        local hash_bin = require("ngx.crypto").digest("sha512", raw_token)
        -- 转换为十六进制格式
        local hex_hash = require("resty.string").to_hex(hash_bin)
        ngx.var.obfuscated_token = hex_hash
    }
    # 其他业务配置...
}

这个方案同样不需要第三方模块,OpenResty自带ngx.crypto和resty.string模块,同步计算哈希后赋值给变量,直接用于日志。


关键注意点

不管用njs还是Lua,都必须用同步哈希接口——因为Nginx的日志生成阶段是同步执行的,不支持异步回调,这也是你之前用async函数失败的核心原因。

内容的提问来源于stack exchange,提问作者dstromberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:00:15