如何保护 JavaScript 应用程序的 API 调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18516410/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 12:14:39  来源:igfitidea点击:

How can you secure a JavaScript application's API calls?

javascriptapisecurity

提问by tmsimont

I have a JavaScript application.

我有一个 JavaScript 应用程序。

It's built with jQuery.

它是用 jQuery 构建的。

It uses $.get()to pull JSON data from a server, and uses the data to load a puzzle.

它用于$.get()从服务器提取 JSON 数据,并使用该数据加载拼图。

I want to distribute the JavaScript application to clients, and make it easy for them to install.

我想将 JavaScript 应用程序分发给客户,并使他们易于安装。

I'd like it to simply give them a JavaScript block they can drop into their page, and it will interact with my API.

我希望它简单地给他们一个 JavaScript 块,他们可以放入他们的页面,并且它会与我的 API 交互。

I'm not passing sensitive data, any my API is protecting the database from SQL injection, etc.

我没有传递敏感数据,我的任何 API 都在保护数据库免受 SQL 注入等。

I just want to try to prevent unauthorized use of my API, and I can't think of a way to do that with JavaScript, since anyone with a DOM inspector can scrape any credentials from any variables or can monitor any server traffic POST or GET data...

我只是想尝试防止未经授权使用我的 API,我想不出用 JavaScript 来做到这一点的方法,因为任何拥有 DOM 检查器的人都可以从任何变量中获取任何凭据,或者可以监控任何服务器流量 POST 或 GET数据...

Would it be possible to authenticate the referrer on the other side?

是否可以验证另一端的推荐人?

I know that's not bulletproof, but it's not sensitive data. I just want to reduce the unauthorized use as much as possible..

我知道这不是防弹的,但它不是敏感数据。我只是想尽可能减少未经授权的使用..

Any ideas?

有任何想法吗?

note: I know obfuscating an API key or something is futile, I'm wondering what other controls I could put in place other than a traditional key to identify the caller to the API.. I have full control over the API itself so I could do anything on that side of things...

注意:我知道混淆 API 密钥或某些东西是徒劳的,我想知道除了传统的密钥之外,我还可以设置哪些其他控件来识别 API 的调用者。我可以完全控制 API 本身,因此我可以在这方面做任何事情......

回答by

JavaScript authentication has holes

JavaScript 身份验证存在漏洞

With JavaScript, just about any authentication system is going to have holes, simply because the code runs directly in the browser and can be seen by anyone (as can the network calls). So there are a couple of things you can try, depending on your situation.

使用 JavaScript,几乎任何身份验证系统都会有漏洞,因为代码直接在浏览器中运行并且任何人都可以看到(网络调用也可以)。因此,您可以尝试几种方法,具体取决于您的情况。

IP whitelisting

IP白名单

If you are distributing this application to a small subset of clients, and you know exactly where they will be accessing it from, you could use IP whitelisting. This really is the only way to completely secure the API. However this method is very cumbersome, since with every new client you have to update the API whitelist, and considering what you're talking about here probably not what you're looking for (but I mention it just because it is a possibility).

如果您将此应用程序分发给一小部分客户端,并且您确切知道他们将从哪里访问它,则可以使用 IP 白名单。这确实是完全保护 API 的唯一方法。然而,这种方法非常麻烦,因为对于每个新客户端,您都必须更新 API 白名单,并且考虑到您在这里谈论的内容可能不是您要查找的内容(但我提到它只是因为它是一种可能性)。

Access tokens

访问令牌

Another method is access tokens. This is a common method used by sites such as Facebook. There are two methods to do this. One is to just give each client a secret key. You can have the same secret key for everyone, but this is not very secure. Having a different secret key for everyone allows you to not only track usage, but also revoke access privs if necessary.

另一种方法是访问令牌。这是 Facebook 等网站常用的方法。有两种方法可以做到这一点。一种是只给每个客户端一个密钥。您可以为每个人使用相同的密钥,但这不是很安全。为每个人使用不同的密钥不仅可以跟踪使用情况,还可以在必要时撤销访问权限。

The first method for access tokens is to just give it inside the JS client. However this means that anyone who looks at the source will be able to access your key, and make requests using it.

访问令牌的第一种方法是在 JS 客户端内提供它。但是,这意味着查看源的任何人都可以访问您的密钥,并使用它发出请求。

The second method is to have the secret key stored somewhere on the SERVER of the website where your client runs. This server can then make a server-to-server call using that key to obtain a temporary session token. People will still be able to access the temporary session token via the front-end, but they will have to access this site first in order to get it (this allows you to pass off responsibility for handling this to the website operator) and the token will eventually expire. However this means there needs to be some server-side code, and the app won't just be a drag and drop thing.

第二种方法是将密钥存储在您的客户端运行的网站的服务器上的某处。然后,该服务器可以使用该密钥进行服务器到服务器调用以获取临时会话令牌。人们仍然可以通过前端访问临时会话令牌,但他们必须先访问该站点才能获得它(这允许您将处理此问题的责任转嫁给网站运营商)和令牌最终会过期。然而,这意味着需要一些服务器端代码,应用程序不会只是拖放。

For the method given above you can also look into things like OAuth, to avoid re-inventing the wheel.

对于上面给出的方法,您还可以查看OAuth 之类的内容,以避免重新发明轮子。

Whitelist hard-cap

白名单硬顶

Another possible thing using IPs is to set a hard-cap on either how often or how much per day a specific IP can hit the whitelist. Though you may run into problems with users who REALLY like the puzzles, this will prevent some of the potential abuse.

使用 IP 的另一个可能的事情是对特定 IP 可以进入白名单的频率或每天设置一个硬上限。虽然您可能会遇到真正喜欢谜题的用户的问题,但这将防止一些潜在的滥用。