Angular 6,我应该将秘密环境变量放在 environment.ts 文件中吗?

Posted

技术标签:

【中文标题】Angular 6,我应该将秘密环境变量放在 environment.ts 文件中吗?【英文标题】:Angular 6, should I put secret environment variables in environment.ts file? 【发布时间】:2018-12-31 13:28:38 【问题描述】:

有两个子问题:

    我应该将秘密环境变量放在environment.ts 文件中吗?

    process 变量 shim 消失了。如果我使用它,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 摆脱了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.yamlDockerfile 以在 docker 容器中运行我的前端应用程序。

这是工作流程:

    写入Dockerfile,运行npm run build命令并将./build目录复制到docker容器的nginx静态文件目录。 ./build目录包含index.htmlbundle.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 文件。 没有后端服务。 将环境变量文件添加到.gitignore,不要推送到SCM(Github、GitLab等)

【问题讨论】:

您的网站是否设计为公开的?访问令牌应该是公共信息吗?如果是,则将其构建到 JS 代码中;否则将其隐藏在后端服务器中。您可以在前端隐藏任何内容。 将敏感数据放在源代码中根本不是一个好主意(出于安全措施),看看如何设置外部环境变量smaillns.medium.com/… 【参考方案1】:

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 集群中运行它,如果您将令牌作为角度环境变量,它不会使您的令牌安全,因为公开的东西不能保密。

您似乎没有理解重点:GitHub 给您一个错误并且不允许推送代码,您应该已经感谢它在您的架构中发现了问题。如果您想解决问题,请使用上述解决方案。如果你想简单地绕过 GitHub 的验证并且你不关心安全性,那么只需将你的令牌字符串分成两部分并将其分开存储,GitHub 将无法找到它。

更新第 3 部分的答案:

您可以直接从前端执行 GitHub 的 Oauth2 请求。您的每个用户都应该在那里拥有一个帐户,这将解决您的所有问题。这实际上与作为解决方案 #2 提出的相同。

如果您使用带有后端的解决方案 #1,出于开发目的,只需预先设置 cookie 或使用 localStorage.setItem('your-token-here')。这对于开发目的来说已经绰绰有余了。

【讨论】:

是的,我知道这一点,无论是通过process.env 还是environment.ts ,编译构建后,最终的bundle.js 文件都会包含运行时的所有环境变量,甚至是秘密环境变量。 那么它们就不是秘密了。这才是重点。您可以将它们存储在 git 中或立即在弹出窗口中显示给用户 - 这几乎是相同级别的安全性。前端代码不是任何秘密变量的地方。 回复Answer to updated part 2:,哦不,我只是想开发一个Angular 6前端应用。 Kubernetes、docker-machine……这些东西都是生产就绪的东西。这增加了太多东西。只是为了开发Angular 6 前端?不!甚至直接从您的前端执行 GitHub 的 Oauth2 请求,这也太繁重了。就像我说的,我不想在一开始就建立一个完整的大系统。只是为了秘密的环境变量?不!最后一个建议很简单而且足够好。将我的 access_token 直接存储到 localStorage。 kubernetes 的事情是讽刺 :) 请检查答案的更新顶部。我认为这是我们讨论的主要内容 看起来唯一的解决方案是拥有一个后端?我在同一条船上。我有一个工具可以对 bitbucket 和 jira 进行 api 调用。目前我在代码中对用户名/密码进行硬编码,但我想将其移动到 .env...该工具不需要要求登录,它将使用我的只读凭据...

以上是关于Angular 6,我应该将秘密环境变量放在 environment.ts 文件中吗?的主要内容,如果未能解决你的问题,请参考以下文章

目标文件里的秘密

使用 tox 和 Github Action 访问环境变量

RESTful URL:我应该把语言环境放在哪里? example.com/en/page 与 example.com/page?locale=en

为啥以及如何将秘密放入 Node.js 的环境变量中?

如何使用 cloudbuild 将秘密管理器秘密传递给 app.yaml 中的应用引擎环境变量

我应该将 Angular 代码放在这个 Mean.js 应用程序中的啥位置以使该列表可排序?