angular - Angular 6,我应该将秘密环境变量放在 environment.ts 文件中吗?
问题描述
有两个子问题:
我应该将秘密环境变量放在
environment.ts
文件中吗?process
变量垫片消失了。如果我使用它,tsc
会抛出一个错误:Cannot find name 'process'
.
这是我的事情:
关于 Q1:我认为将秘密环境变量放在 environment.ts 文件中是不正确的。因为这些文件会被推送到源代码管理,比如 GitHub、GitLab、bitbucket。这不安全。所以我认为秘密环境变量应该通过process.env
,process.env.ACCESS_TOKEN
或者,如果使用docker-compose,应该将秘密环境变量放在.env
文件中并将这个文件添加到.gitignore
文件中。
关于 Q2:如果我使用 Heroku 来设置我的环境变量,它取决于process
变量。现在,angular6 摆脱了 shim process
,我该如何使用 Heroku?此外,使用 docker-compose 通过.env
文件传递环境变量也取决于process
。
如果使用.env
docker-compose 文件,就会出现一个新问题:How to pass variables in .env file to angular6 environment.ts file
更新1:
这是一个案例:
一、没有后台
我使用 GitHub API 和另一个开放的 API,并且有一个名为 的环境变量access_token
,如果我把它放在environment.ts
文件中并将我的前端源代码推送到 Github,Github 会检测到秘密信息并给我一个警告,他们说:
您不应该将 GitHub 访问令牌放在您的源代码中并将其推送到 repo,这样他们就会撤销我的访问令牌。
所以我想使用process.env.ACCESS_TOKEN
,但是process
变量 shim 没有了Angular6
,我该如何解决这个问题?我应该将environment.ts
文件添加到.gitignore
文件中还是什么?
更新 2
这是另一个案例
继续更新 1。现在,我在容器中添加docker-compose.yaml
并Dockerfile
运行我的前端应用程序。docker
这是工作流程:
写入
Dockerfile
、运行npm run build
命令并将./build
目录复制到容器的nginx
静态文件目录。docker
该./build
目录包含index.html
,bundle.js
文件等。将
access_token
和其他秘密环境变量放入.env
文件中。运行以在容器
docker-compose up
中运行我的应用程序。docker
我认为这个工作流程是可靠的。无需后端服务,文件中包含秘密环境变量.env
,.gitignore
因此.env
不会被推送到 Github repo。
但是,关键是process
垫片不见了。我无法通过process
.
更新 3
我认为我的问题集中在前端应用程序开发阶段。我继续用上面的案例来解释。
为了准备好生产,工作流程是:
当 oauth 工作流程完成后,为 github oauth 创建一个后端服务。后端服务发送
access_token
到前端。前端登录成功,
access_token
从后端服务获取并存储在localStorage或cookie中。不需要access_token
从process.env
但是对于开发阶段,一般情况下前端和后端开发是分开的。所以,前端不应该依赖后端服务。
而且我不想在一开始就构建整个大系统。
所以我认为问题是:
在哪里存储秘密环境变量以及如何在Angular6
前端应用程序代码中获取?需要考虑几种情况:
- 使用 PaaS Heroku 配置变量
- Dockerized(docker-compose, Dockerfile),
.env
文件。 - 没有后端服务。
- 将环境变量文件添加到
.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 用户推送代码的后端服务。这意味着令牌将存储在后端的环境变量中,这是一种非常合适的做事方式
- 要求您的用户为每次推送输入令牌或询问一次并将其存储在 localStorage 中。这只有在每个用户都有自己/不同的令牌时才有意义
对更新的第 2 部分的回答:
您可以在前端构建一个 docker,在托管在世界上最安全的服务器上的虚拟机内的 kubernetes 集群中运行它,如果将它作为 angular 环境变量,它不会使您的令牌安全,因为什么是公共的不能保密。
您似乎没有理解重点:GitHub 给您一个错误并且不允许推送代码,您应该已经很感激它在您的架构中发现了问题。如果您想解决问题,请使用上述解决方案。如果您想简单地绕过 GitHub 的验证并且您不关心安全性,那么只需将您的令牌字符串分成两部分并将其分开存储,GitHub 将无法找到它。
回答更新的第 3 部分:
您可以直接从前端执行 GitHub 的 Oauth2 请求。您的每个用户都应该在那里拥有一个帐户,这将解决您的所有问题。这实际上与作为解决方案#2 提出的相同。
如果您使用带有后端的解决方案 #1,出于开发目的,只需预先设置 cookie 或使用localStorage.setItem('your-token-here')
. 这对于开发目的来说已经绰绰有余了。
推荐阅读
- magento-1.9 - Magento 1.9 - 在订单历史页面中显示可配置的产品图片
- python - 以两种或多种方式连接到服务,在 Python 中委托方法执行
- android - TranslateAnimation 第一次不起作用
- ruby-on-rails - Rails 没有这样的文件或目录@rb_sysopen。无法从上传目录获取文件内容
- python - 如何使用 Tkinter 在 Python 中将 Enter 键连接到按钮
- mongodb - 地理空间查询不适用于某些位置
- android - 改造 POST 请求 - 解析两个具有相同名称的 JSON 对象
- php - PHP | 如何用'for'读取文件行?
- java - TCP 连接在 Java 中工作,但在 C# 中不工作
- powershell - 使用 PowerShell 忽略带有 SQL 查询的循环的空结果