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
相关产品推荐
相关产品推荐

