如何在客户端存储API密钥(令牌),使用户无法查看或访问?

huangapple go评论82阅读模式
英文:

How do you store an API key (token) client side without the user being able to see/access it?

问题

我正在处理涉及敏感客户信息的项目。显然,安全性是首要任务。
我们最近创建了一个API,希望用它来访问数据库以访问/修改数据。
在客户端存储API令牌的最佳方式是什么?我们目前正在使用HTML模板文件的标签来存储CSRF令牌,但我们不希望API令牌可见。

这是用于CSRF令牌的代码,它有效:

// 捕获并存储CSRF令牌
useEffect(() => {
  const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
  setToken(csrfToken);
  console.log({ sessionToken, csrfToken });
}, []);

这是我们用作模板的索引文件的标签:

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="csrf-token" content="{{ csrf_token }}">
  <meta name="api-token" content="{{ request.session.api_token }}">
</head>

这也有效,但如果有人检查页面,API令牌就会可见。

我们正在使用Django / Python后端和React前端。
这是否涉及使用Cookie?还是会更加复杂?
非常感谢任何帮助。如果需要查看代码的其他部分,请告诉我。

我尝试将API令牌添加到标签和会话存储中。这两个选项都不正确。

英文:

I am working on a project that is handling sensitive customer information. Obviously security is a high priority.
We have recently created an API that we want to use to be able to access the database to access / modify the data.
What is the best way to store an API token client side? We currently are using the meta tag of the html template file to store the csrf token, but we do not want the API token to be visible.

Here is the code for the csrf token and it works.

 //Capture and store the csrf Token
  useEffect(() =&gt; {
    const csrfToken = document.querySelector(&#39;meta[name=&quot;csrf-token&quot;]&#39;).getAttribute(&#39;content&#39;);
    setToken(csrfToken);
    console.log({sessionToken, csrfToken});
  }, []);

Here is the <head> tag for the index file we are using as a template

&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;meta name=&quot;csrf-token&quot; content=&quot;{{ csrf_token }}&quot;&gt;
  &lt;meta name=&quot;api-token&quot; content=&quot;{{ request.session.api_token }}&quot;&gt;
&lt;/head&gt;

This also works, but then the API token is visible if someone inspects the page.

We are using a Django / Python backend and a React front end.
Would this involve the use of cookies? Or does it get more complicated than that?
Any help would be greatly appreciated. Let me know if you need to see any other parts of the code.

I tried adding it to the meta tag, and adding it to session storage. Neither of these options felt correct.

答案1

得分: 2

在客户端存储API密钥而不使其暴露给用户可能会很具有挑战性,因为客户端代码本质上是对用户可访问的。然而,有一些技术可以用来增强安全性。以下是一些选项:

服务器端代理: 与直接在客户端存储API密钥不同,您可以创建一个服务器端代理,充当您的客户端和API之间的中间人。客户端向您的服务器发送请求,然后服务器在与实际API的服务器间通信中包含API密钥。这样,API密钥对客户端保持隐藏。我在GitHub上找到了关于这种方法的信息,也许值得您参考一下:https://github.com/eofs/django-rest-framework-proxy

基于令牌的身份验证: 考虑实施基于令牌的身份验证,例如JSON Web Tokens(JWT),其中客户端使用用户特定的令牌来访问受保护的资源。服务器可以生成和管理这些令牌,并在每个请求上验证它们。这种方法避免了直接向客户端暴露API密钥。有关JWT以及在Django Rest Framework中实施的更多信息,请参见:https://www.freecodecamp.org/news/how-to-use-jwt-and-django-rest-framework-to-get-tokens/

后端会话存储: 您提到使用Django作为后端的一个选项是在对用户进行身份验证后将API密钥安全地存储在后端会话存储中。会话可以与用户的经过身份验证的会话相关联,允许服务器代表用户处理API请求,而不向客户端暴露API密钥。参见:https://docs.djangoproject.com/en/4.2/topics/http/sessions/

服务器端环境变量: 这是一种常见做法;您可以将API密钥作为服务器端环境变量存储。这样,密钥对客户端代码保持隐藏。然后,您的后端代码可以访问环境变量并将密钥用于API请求。

请记住,虽然这些方法增强了安全性,但没有绝对可靠的方法可以完全隐藏敏感信息,一旦坚决入侵客户端代码的攻击者获得访问权,因此,实施额外的安全措施如服务器端验证、速率限制和监控来保护敏感客户信息至关重要。

英文:

Storing an API key client-side without exposing it to users can be challenging, as client-side code is inherently accessible to users. However, there are some techniques you can use to enhance security. Here are a few options:

Server-side Proxy: Instead of storing the API key directly on the client-side, you can create a server-side proxy that acts as an intermediary between your client and the API. The client sends requests to your server, which then includes the API key in the server-to-server communication with the actual API. This way, the API key remains hidden from the client. I found this on github about this method, maybe it is worth you taking a look at it: https://github.com/eofs/django-rest-framework-proxy

Token-based Authentication: Consider implementing token-based authentication, such as JSON Web Tokens (JWT), where the client exchanges a user-specific token for access to protected resources. The server can generate and manage these tokens, validating them on each request. This approach avoids exposing the API key directly to the client. More about JWT and implementing it with Django Rest Framework here: https://www.freecodecamp.org/news/how-to-use-jwt-and-django-rest-framework-to-get-tokens/

Backend Session Storage: You mentioned using Django as the backend. One option is to store the API key securely in the backend session storage after authenticating the user. The session can be associated with the user's authenticated session, allowing the server to handle API requests on behalf of the user without exposing the API key to the client. See: https://docs.djangoproject.com/en/4.2/topics/http/sessions/

Server-Side Environment Variables: This is a common practice; you can store the API key as an environment variable on the server-side. This way, the key remains hidden from the client code. Your backend code can then access the environment variable and use the key for API requests.

Remember, while these approaches enhance security, there is no foolproof way to completely hide sensitive information from a determined attacker who gains access to the client-side code. Therefore, it's crucial to implement additional security measures like server-side validation, rate limiting, and monitoring to protect sensitive customer information.

huangapple
  • 本文由 发表于 2023年2月14日 01:16:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定