Angular 6、我应该把秘密环境变量放在environment.ts文件中吗?
Angular 6, should I put secret environment variables in environment.ts file?
有两个子问题:
我应该把秘密环境变量放在 environment.ts
文件中吗?
process
变量 shim 消失了。如果我使用它,tsc
会抛出错误:Cannot find name 'process'
.
这是我的东西:
关于问题 1:我认为将秘密环境变量放入 environment.ts 文件中是不正确的。因为这些文件会被推送到源码管理,像GitHub,GitLab,bitbucket。这不安全。所以我认为秘密环境变量应该通过 process.env
传递,比如 process.env.ACCESS_TOKEN
,或者,如果使用 docker-compose,应该将秘密环境变量放在 .env
文件中并添加此文件到 .gitignore
文件。
关于Q2:如果我使用Heroku设置我的环境变量,这取决于process
变量。现在,angular6 去掉了 process
的 shim,如何使用 Heroku?此外,使用 docker-compose 通过 .env
文件传递环境变量也取决于 process
。
如果使用.env
文件进行docker-compose,会出现一个新问题:How to pass variables in .env file to angular6 environment.ts file
更新 1:
这里有一个案例:
首先,没有后端
我用的是GitHubAPI,另外打开一个API,里面有个环境变量叫access_token
,
如果我把它放在 environment.ts
文件中并将我的前端源代码推送到 Github,Github 将检测到秘密信息并给我一个警告,他们说:
You should not put the GitHub access token in your source code and push it to repo, so they will revoke my access token.
所以我想使用process.env.ACCESS_TOKEN
,但是process
变量shim在Angular6
中没有了,我该如何解决这个问题?我应该将 environment.ts
文件添加到 .gitignore
文件还是什么?
更新 2
还有一个案例
继续更新 1。现在,我将 docker-compose.yaml
和 Dockerfile
添加到 运行 我在 docker
容器中的前端应用程序。
工作流程如下:
写入Dockerfile
,运行npm run build
命令,将./build
目录复制到[=34=的nginx
静态文件目录下] 容器。 ./build
目录包含 index.html
、bundle.js
文件等。
将 access_token
和其他秘密环境变量放入 .env
文件。
运行 docker-compose up
到 运行 我在 docker
容器中的应用程序。
我认为这个工作流程很可靠。无需后端服务,.env
和.gitignore
中的秘密环境变量包含.env
文件,因此不会推送到Github repo.
但是,关键是 process
shim 不见了。我无法通过process
.
获取环境变量
更新 3
我认为我的问题集中在前端应用程序开发阶段。
我继续用上面的案例来解释。
为生产就绪,工作流程为:
在完成 oauth 工作流后,为 github oauth 创建一个后端服务。后端服务发送 access_token
到前端。
前端登录成功,从后端服务获取access_token
存入localStorage或cookie。不需要从 process.env
得到 access_token
但是对于开发阶段,一般情况下前后端开发是分开的。所以,前端不应该依赖后端服务。
而且我不想一开始就构建整个大系统。
所以我认为问题是:
在哪里存储秘密环境变量以及如何在Angular6
前端应用程序代码中获取?需要考虑几种情况:
- 使用 PaaS Heroku 配置变量
- Dockerized(docker-compose, Dockerfile),
.env
file.
- 没有后台服务。
- 将环境变量文件添加到
.gitignore
,不要推送到SCM(Github、GitLab等)
TL;博士
您不应将 environment.ts
视为类似于 process.env
的内容。
名字相似但行为完全不同。 environment.ts
中的所有设置将直接转到您的代码。这就是为什么以任何方式向 environments.ts
保密都是不安全的。
环境变量 (process.env
) 的浏览器替代方案是
- sessionStorage:表现得像
export VAR=value
- localStorage: 表现得像
export VAR=value
但放入你的 .bash_profile
并且跨会话持久
- indexedDB:与 localStorage 相同,唯一不同的是它的 异步
- cookies:看起来不像
process.env
,但在某些情况下仍然可以自动将秘密发送到某些后端
- 后端:始终可以选择从后端获取机密,异步
长版
客户端应用程序中没有秘密这样的东西。由于您在浏览器中的代码将能够获取这些变量,因此每个人都将能够在 运行 时间内获取这些变量。
这意味着,您显式或隐式使用的所有库、用户的浏览器扩展程序以及任何能够嗅探您/您的用户流量的人 - 所有这些都将很容易获得您的秘密。
不管你怎么通过。通过 process.env 或 environment.ts,所有这些都将在生成的 main.js 文件中结束,在那里它们不再是秘密,进一步的讨论实际上是无用的。
更新第 1 部分的答案:
如果 access_token
是您的(或您的合成用户)令牌,那么您有两个选择:
- 编写代表此 Github 用户推送代码的后端服务。这意味着令牌将存储在后端的环境变量中,这是一种非常合适的做事方式
- 要求您的用户在每次推送时输入令牌,或者询问一次并将其存储在本地存储中。只有当每个用户都有自己的/不同的令牌时,这才有意义
更新第 2 部分的答案:
你可以在你的前端周围构建一个 docker,运行 它在一个虚拟机内的 kubernetes 集群中,该虚拟机托管在世界上最安全的服务器上,它不会使你的令牌如果你把它作为 angular 环境变量是安全的,因为 public 不能是秘密的。
您似乎没有理解要点:GitHub 给您一个错误并且不允许推送代码,您应该已经很感激它在您的体系结构中发现了问题。如果您想解决问题,请使用上述解决方案。如果您想简单地绕过 GitHub 的验证并且您不关心安全性,那么只需将您的令牌字符串分成两部分并将其分开存储,并且 GitHub 将无法找到它。
更新第 3 部分的答案:
您可以直接从前端执行 GitHub 的 Oauth2 请求。您的每个用户都应该在那里拥有一个帐户,这将解决您所有的问题。这实际上与作为解决方案 #2 提出的相同。
如果您使用带有后端的解决方案 #1,出于开发目的,只需预先设置 cookie 或使用 localStorage.setItem('your-token-here')
。这对于开发目的来说绰绰有余。
有两个子问题:
我应该把秘密环境变量放在
environment.ts
文件中吗?process
变量 shim 消失了。如果我使用它,tsc
会抛出错误:Cannot find name 'process'
.
这是我的东西:
关于问题 1:我认为将秘密环境变量放入 environment.ts 文件中是不正确的。因为这些文件会被推送到源码管理,像GitHub,GitLab,bitbucket。这不安全。所以我认为秘密环境变量应该通过 process.env
传递,比如 process.env.ACCESS_TOKEN
,或者,如果使用 docker-compose,应该将秘密环境变量放在 .env
文件中并添加此文件到 .gitignore
文件。
关于Q2:如果我使用Heroku设置我的环境变量,这取决于process
变量。现在,angular6 去掉了 process
的 shim,如何使用 Heroku?此外,使用 docker-compose 通过 .env
文件传递环境变量也取决于 process
。
如果使用.env
文件进行docker-compose,会出现一个新问题:How to pass variables in .env file to angular6 environment.ts file
更新 1:
这里有一个案例:
首先,没有后端
我用的是GitHubAPI,另外打开一个API,里面有个环境变量叫access_token
,
如果我把它放在 environment.ts
文件中并将我的前端源代码推送到 Github,Github 将检测到秘密信息并给我一个警告,他们说:
You should not put the GitHub access token in your source code and push it to repo, so they will revoke my access token.
所以我想使用process.env.ACCESS_TOKEN
,但是process
变量shim在Angular6
中没有了,我该如何解决这个问题?我应该将 environment.ts
文件添加到 .gitignore
文件还是什么?
更新 2
还有一个案例
继续更新 1。现在,我将 docker-compose.yaml
和 Dockerfile
添加到 运行 我在 docker
容器中的前端应用程序。
工作流程如下:
写入
Dockerfile
,运行npm run build
命令,将./build
目录复制到[=34=的nginx
静态文件目录下] 容器。./build
目录包含index.html
、bundle.js
文件等。将
access_token
和其他秘密环境变量放入.env
文件。运行
docker-compose up
到 运行 我在docker
容器中的应用程序。
我认为这个工作流程很可靠。无需后端服务,.env
和.gitignore
中的秘密环境变量包含.env
文件,因此不会推送到Github repo.
但是,关键是 process
shim 不见了。我无法通过process
.
更新 3
我认为我的问题集中在前端应用程序开发阶段。 我继续用上面的案例来解释。
为生产就绪,工作流程为:
在完成 oauth 工作流后,为 github oauth 创建一个后端服务。后端服务发送
access_token
到前端。前端登录成功,从后端服务获取
得到access_token
存入localStorage或cookie。不需要从process.env
access_token
但是对于开发阶段,一般情况下前后端开发是分开的。所以,前端不应该依赖后端服务。
而且我不想一开始就构建整个大系统。
所以我认为问题是:
在哪里存储秘密环境变量以及如何在Angular6
前端应用程序代码中获取?需要考虑几种情况:
- 使用 PaaS Heroku 配置变量
- Dockerized(docker-compose, Dockerfile),
.env
file. - 没有后台服务。
- 将环境变量文件添加到
.gitignore
,不要推送到SCM(Github、GitLab等)
TL;博士
您不应将 environment.ts
视为类似于 process.env
的内容。
名字相似但行为完全不同。 environment.ts
中的所有设置将直接转到您的代码。这就是为什么以任何方式向 environments.ts
保密都是不安全的。
环境变量 (process.env
) 的浏览器替代方案是
- sessionStorage:表现得像
export VAR=value
- localStorage: 表现得像
export VAR=value
但放入你的.bash_profile
并且跨会话持久 - indexedDB:与 localStorage 相同,唯一不同的是它的 异步
- cookies:看起来不像
process.env
,但在某些情况下仍然可以自动将秘密发送到某些后端 - 后端:始终可以选择从后端获取机密,异步
长版
客户端应用程序中没有秘密这样的东西。由于您在浏览器中的代码将能够获取这些变量,因此每个人都将能够在 运行 时间内获取这些变量。
这意味着,您显式或隐式使用的所有库、用户的浏览器扩展程序以及任何能够嗅探您/您的用户流量的人 - 所有这些都将很容易获得您的秘密。
不管你怎么通过。通过 process.env 或 environment.ts,所有这些都将在生成的 main.js 文件中结束,在那里它们不再是秘密,进一步的讨论实际上是无用的。
更新第 1 部分的答案:
如果 access_token
是您的(或您的合成用户)令牌,那么您有两个选择:
- 编写代表此 Github 用户推送代码的后端服务。这意味着令牌将存储在后端的环境变量中,这是一种非常合适的做事方式
- 要求您的用户在每次推送时输入令牌,或者询问一次并将其存储在本地存储中。只有当每个用户都有自己的/不同的令牌时,这才有意义
更新第 2 部分的答案:
你可以在你的前端周围构建一个 docker,运行 它在一个虚拟机内的 kubernetes 集群中,该虚拟机托管在世界上最安全的服务器上,它不会使你的令牌如果你把它作为 angular 环境变量是安全的,因为 public 不能是秘密的。
您似乎没有理解要点:GitHub 给您一个错误并且不允许推送代码,您应该已经很感激它在您的体系结构中发现了问题。如果您想解决问题,请使用上述解决方案。如果您想简单地绕过 GitHub 的验证并且您不关心安全性,那么只需将您的令牌字符串分成两部分并将其分开存储,并且 GitHub 将无法找到它。
更新第 3 部分的答案:
您可以直接从前端执行 GitHub 的 Oauth2 请求。您的每个用户都应该在那里拥有一个帐户,这将解决您所有的问题。这实际上与作为解决方案 #2 提出的相同。
如果您使用带有后端的解决方案 #1,出于开发目的,只需预先设置 cookie 或使用 localStorage.setItem('your-token-here')
。这对于开发目的来说绰绰有余。