虽然@Antonia Blair 已经回答了这个问题,但我想通过一些基本规则来了解更多。
1:大多数答案都建议使用 .env 文件。我想一次性明确说明。env 不是在这里添加任何安全层。名称所描述的 .env 仅用于在构建时设置环境。例如通过使用环境变量,您可以在构建时设置一些全局值,并且可以在运行时在应用程序中访问这些值。
2:Reactjs 只是一个在客户端浏览器中运行您的 javascript 代码的框架。因此客户端可以完全访问 javascript (Reactjs) 代码。客户端没有什么是安全的。因此,永远不要想通过将所有代码保留在客户端来使某些东西安全或对客户端隐藏。每当您需要向客户端隐藏某些内容时,您需要在服务器端合并某些内容。只有服务器端代码对客户端来说是安全的。
3:所以你要做的是,你将把你的安全密钥保存在服务器端。
假设您的安全密钥的目的是为您的客户制作一个 cookie。所以客户端需要cookie而不是安全密钥,对吗?因此,客户端向服务器请求 cookie,服务器使用安全密钥制作 cookie 并将 cookie 返回给客户端。毕竟客户端只是来吃饼干的,不知道我们怎么做饼干对吧?
4:所以经验法则是,无论您有什么机密数据,都将其保存在服务器上。服务器将使用这些机密数据并将结果数据返回给客户端。
编辑 Sep_06_2021
一位用户要求提供一个编码示例,因此我将提出一个我使用上述技术处理的实时场景。
这是我的用例
-
我有一个向非公共 API 提交公共表单的 Reactjs 应用程序。
-
非公共 API 是 Harvest API 托管的
https://www.greenhouse.io/
-
此 API 需要一个身份验证标头才能使用它发出请求。我已向 API 所有者订阅,并从他们那里收到了一个秘密令牌,我可以将其用于我的请求以访问他们的 API
-
当然,我想保持我的令牌个人化,不要将其暴露给
公众用户
-
我已经使用 axios 客户端与 API 通信
我有两种方法来执行上述场景
错误的方法
我直接从我的 Reactjs 应用程序向 API 发出请求
下面是我想要访问的 API 端点
apiURL=https://boardsapi.greenhouse.io/v1/boards/xyz/jobs/"+jobId+""
上述 API 端点需要一个授权标头,我将在其中提供我的秘密令牌。
const config = {
headers: {
"Authorization": "Basic ####MySecretCode#####",
} };
假设我想用这个请求发布一些表单数据
let formData=MyFormData
我现在可以使用如下所示的 axios 客户端发送我的请求
let result=await axios.post(apiURL, formData,config);
使用上述技术,我可以成功地将表单数据发布到 Harvest API。
但就像我说的那样,与此 API 进行通信是一种不正确的方式。因为我在客户端暴露了我的秘密令牌。
正确的方法
我在 Nodejs 上构建了一个 API 并公开托管。
假设我想将一些表单数据发布到 Harvest API
let formData=MyFormData
我不会直接从我的客户端应用程序中访问 Harvest API。相反,我已经在我的中间件 API 中公开了端点来处理这个问题。
假设下面是我想要访问的中间件 API 的端点 URL
apiURL=https://proxy-server/apply
上述 API 端点不需要授权标头。所以我可以使用下面的 axios 客户端发送帖子请求
let result=await axios.post(apiURL, formData);
区别很明显。这次我没有在我的请求中提供秘密令牌。因为这不是对 Harvest API 的直接请求,而是对由我开发和托管的中间件 API 的请求。
我在我的中间件 API 中收到此请求,将我的秘密令牌与它一起添加并将其转发到 Harvest API。 Harvest API 的响应返回到我们的 middle_ware API 并因此转发回我们的 Reactjs 客户端应用程序。
秘密令牌现在驻留在我的服务器端 API 中,对外部用户安全。