Log*_*ler 35 escaping environment-variables node.js
我正在尝试使用环境变量将RSA私钥加载到我的nodejs应用程序中,但新行似乎正在自动转义.
假设以下内容,假设PRIVATE_KEYenv var设置为以下(不是我的实际键):
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END RSA PRIVATE KEY-----"
Run Code Online (Sandbox Code Playgroud)
如果我console.log直接用前面的字符串调用,我得到以下输出:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
您可以看到新行字符正在受到尊重.但是,如果我调用console.log(process.env["PRIVATE_KEY"]),则输出包含\n文字而不是实际换行符:
-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
我一直试图在网上找到关于节点如何处理环境变量而没有运气的更多信息.如何在维护换行符时通过env变量加载此密钥?如果那不可能,我该如何恢复它们?
Adr*_*doy 54
只需\n在使用前替换值:
var private_value = process.env.PRIVATE_KEY.replace(/\\n/g, '\n');
console.log(private_value);
Run Code Online (Sandbox Code Playgroud)
结果会正确:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
JBa*_*lin 12
dotenv支持带双引号的换行符:
双引号值扩展新行
MULTILINE="new\nline"变成Run Code Online (Sandbox Code Playgroud){MULTILINE: 'new line'}
正如另一个主题中所述,您可以用 base64 编码多行字符串并将其放入 .env 中,如下所示
HTTPS_CA_CERTIFICATE=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDVENDQWZHZ0F3SUJBZ0lVY29lWFp1R
Run Code Online (Sandbox Code Playgroud)
然后在您的应用程序中对其进行解码
var cert = new Buffer(process.env.HTTPS_CA_CERTIFICATE, 'base64').toString('ascii');
Run Code Online (Sandbox Code Playgroud)
节点将使用环境变量,并对其进行转义以避免插值:
% export X="hey\nman"
% echo $X
hey
man
% node
> process.env['X']
'hey\\nman'
>
Run Code Online (Sandbox Code Playgroud)
一种选择是使用实际换行符在节点外部设置变量:
% export X="hey
dquote> man"
% node
> process.env['X']
'hey\nman'
> console.log(process.env['X'])
hey
man
undefined
>
Run Code Online (Sandbox Code Playgroud)
这也适用于脚本文件,只需在引号中使用换行符即可。您也可以进行替换:
% export X="hey\nman\ndude\nwhat"
% node
> console.log(process.env['X'].replace(/\\n/g, '\n'))
hey
man
dude
what
Run Code Online (Sandbox Code Playgroud)
Node.js的,不正确地反映了嵌入式环境变量的实际换行,如下面的bash代码片段演示:
$ PRIVATE_KEY=$'ab\ncde' node -p 'process.env["PRIVATE_KEY"].indexOf("\n")'
2 # 0-based index of the (first) actual newline char. in env. var. 'PRIVATE_KEY'
Run Code Online (Sandbox Code Playgroud)
注意,这$'...'是一种特殊类型的bash字符串,其中转义的转义序列\n 被扩展,因此在上面的命令PRIVATE_KEY中确实用2行定义并作为环境变量传递给node(简单地通过将变量赋值添加到要调用的命令,这是POSIX类shell中的标准功能.
实际上,Node并没有以任何方式解释环境变量的值(这是正确的做法).
必须是你的PRIVATE_KEY变量不包含实际换行符,而是 \n 文字(\char.后跟char.n).
如果分配命令PRIVATE_KEY="..."中的问题是一个外壳命令,这可以解释它:在POSIX样壳,诸如bash,\n内部"..."字符串保留原样.
"..."字符串会插入转义序列,例如\n,这就是为什么直接传递这样的字符串console.log()确实输出换行符的原因; 例如,node -e 'console.log("ab\ncde")'确实输出2行.PRIVATE_KEY="ab\ncde" node -p 'process.env["PRIVATE_KEY"]'(字面上)输出ab\ncde,显示\n保留为字面值.
您有两种方法可以解决您的问题:
最好先用实际的换行符定义你的环境变量 - 见下文.
或者,如果您不控制环境变量的设置方式,请将\n文字扩展为Node.js(JavaScript)代码中的实际换行符:请参阅Adriano Godoy的有用答案.
要使用类似POSIX的shell中的实际换行符进行定义PRIVATE_KEY,请使用以下技术之一:
bash,ksh,zsh:使用ANSI C引号字符串:export PRIVATE_KEY=$'-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----'
Run Code Online (Sandbox Code Playgroud)
dash(以及任何使用的shell脚本sh):export PRIVATE_KEY="$(printf %s '-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----')"
Run Code Online (Sandbox Code Playgroud)
或者,为了更好的可读性,您可以使用here-document命令替换:
export PRIVATE_KEY="$(cat <<'EOF'
-----BEGIN RSA PRIVATE KEY-----
...
...
-----END RSA PRIVATE KEY-----
EOF
)"
Run Code Online (Sandbox Code Playgroud)
如果您使用的是dotenv:我们使用换行符和JSON.parse通过这种方式解决了此问题(这允许在字符串中使用任何反斜杠转义的字符,而不仅仅是\n):
在.env中:
MY_KEY='-----BEGIN CERTIFICATE-----\nabcde...'
Run Code Online (Sandbox Code Playgroud)
在server.ts中:
myKey = JSON.parse(`"${process.env.MY_KEY}"`), // convert special chars
Run Code Online (Sandbox Code Playgroud)
看到线程:https : //github.com/motdotla/dotenv/issues/218
| 归档时间: |
|
| 查看次数: |
8006 次 |
| 最近记录: |