简体   繁体   English

使用指定的客户端密钥设计API

[英]Designing an API with designated client keys

I'm designing a JSON web API and want to distinguish clients by unique IDs, in order to monitor usage and block malicious/misbehaving clients. 我正在设计一个JSON Web API,并希望通过唯一ID来区分客户端,以便监控使用情况并阻止恶意/行为不端的客户端。 The API is NOT encapsulated in a JavaScript library and NOT exclusive to web apps, any client type can use it (desktop, phone, etc.). API不是封装在JavaScript库中,也不是Web应用程序独有的,任何客户端类型都可以使用它(桌面,电话等)。

The problem is, that the web app (official website) is also a client of the API itself , thus would have to expose its API key. 问题是,Web应用程序(官方网站)也是API本身的客户端 ,因此必须公开其API密钥。 As a result, some user could just extract the key from the JavaScript on the page and use it, instead of generating his own key. 因此,某些用户可以从页面上的JavaScript中提取密钥并使用它,而不是生成自己的密钥。

Is it possible to mitigate this problem somehow with some better/smarter design choices, or do I have to live with the fact that anyone using the API in bad faith can exploit this? 是否有可能以某种更好/更聪明的设计选择来某种方式缓解这个问题,或者我是否必须忍受这样一个事实:任何恶意使用API​​的人都可以利用这个?

I have 100% control over the frontend app (EmberJS) and backend servers (Go), so any alternation can be suggested. 我可以100%控制前端应用程序(EmberJS)和后端服务器(Go),因此可以建议任何更改。

  • I'm using rate limiting per session/ip to add an extra protection layer for that case 我正在使用每个会话/ ip的速率限制为该情况添加额外的保护层
  • The twitter.com page was once also a client of its own API. twitter.com页面曾经也是自己API的客户端。 How did they solve that? 他们是如何解决的?

Note: The question is not about authentication or security itself, but how to require 3rd party users to use an API key in addition (!) to authentication! 注意:问题不在于身份验证或安全性本身,而是如何要求第三方用户另外使用API​​密钥(!)进行身份验证!

You should distinguish between web and non-web clients. 您应该区分Web和非Web客户端。 An access key for web cannot be used in non-web and vice-versa. Web的访问密钥不能在非Web中使用,反之亦然。 For web clients, you can do referer checking etc. You could also dynamically create access keys for your application and automatically change them daily (or every session). 对于Web客户端,您可以进行引用检查等。您还可以为应用程序动态创建访问密钥,并每天(或每个会话)自动更改它们。 You can also add some special verification for your app only, eg some additional key that is calculted by obfuscated JS. 您还可以仅为您的应用添加一些特殊验证,例如由混淆的JS计算的一些额外密钥。

Nothing can prevent a malicious user to emulate a browser, execute the JS, manipulate that, and then do bad things - but you can make it annoying enough that they decide it's not worth their effort. 没有什么能阻止恶意用户模仿浏览器,执行JS,操纵它,然后做坏事 - 但是你可以让它烦人,以至于他们认为不值得他们付出努力。 Really important things like permissions etc. obviously need to be checked server-side, so abusing your API should not be much of a problem. 显然需要在服务器端检查权限等非常重要的事情,因此滥用您的API不应该是一个大问题。 You will have to treat API abuse via your site's API key the same as you do with regular web app abuse - IP blocks etc. 您必须通过网站的API密钥处理API滥用行为,与常规网络应用滥用行为相同 - IP阻止等。

You still need to keep API keys for non-web clients secret. 您仍然需要保密非Web客户端的API密钥。 This can only be done unreliably by obfuscation, which you can leave at the hands of the client developer. 这只能通过混淆不可靠地完成,您可以将其留在客户端开发人员手中。 If their key gets leaked and abused, you revoke it, and they will be motivated to fix it. 如果他们的密钥被泄露和滥用,你撤销它,他们将有动力解决它。

Have a look at OAuth 2.0 , they impelement many features that could be useful for you. 看看OAuth 2.0 ,它们会阻止许多可能对您有用的功能。 Even if you don't want to use it, you can take some inspiration from it. 即使你不想使用它,你也可以从中获得灵感。 OpenStreetMap uses OAuth (not sure if 1 or 2) for their flash-based editor; OpenStreetMap使用OAuth(不确定是1还是2)作为基于flash的编辑器; as long as it is called from the same origin by a logged-in user, the OAuth permission granting is done automatically. 只要登录用户从同一来源调用,OAuth权限授予就会自动完成。 For third-party apps, the user needs to do it manually. 对于第三方应用,用户需要手动执行此操作。 You may want to check that out. 您可能想要检查出来。

You will not be able to make your API secure just using a single API key. 只使用一个API密钥,您将无法保证API的安全。 The API key you are describing is basically a public key and you will need some type of private key for secure identification/authentication and a mechanism to deliver it. 您描述的API密钥基本上是一个公钥,您需要某种类型的私钥来进行安全识别/身份验证,并提供一种机制来提供它。

You asked how Twitter got around this issue. 你问过Twitter是如何解决这个问题的。 They use Oath 1.0a. 他们使用Oath 1.0a。 Here is brief description of how it is tied to the API key from a Twitter Developer FAQ . 以下是关于它如何与Twitter Developer FAQ中的API密钥相关联的简要说明。

Most integrations with the API will require you to identify your application to Twitter by way of an API key. 大多数与API的集成将要求您通过API密钥向Twitter标识您的应用程序。 On the Twitter platform, the term "API key" usually refers to what's called an OAuth consumer key. 在Twitter平台上,术语“API密钥”通常指的是所谓的OAuth使用者密钥。 This string identifies your application when making requests to the API. 此字符串在向API发出请求时标识您的应用程序。 In OAuth 1.0a, your "API keys" might refer to the combination of this consumer key and the "consumer secret," a string that used to securely "sign" your requests to Twitter. 在OAuth 1.0a中,您的“API密钥”可能指的是此消费者密钥和“消费者密钥”的组合,这是一个用于安全地“签署”您对Twitter的请求的字符串。 Most requests to Twitter require a user context in addition to the application context. 除了应用程序上下文之外,对Twitter的大多数请求都需要用户上下文。 User context is presented through the use of another kind of token/key called the "access token." 通过使用称为“访问令牌”的另一种令牌/密钥来呈现用户上下文。 See Obtaining access tokens for more information. 有关更多信息,请参阅获取访问令牌。

You can find a lot of great resources on designing API's at Apigee.com . 您可以在Apigee.com上找到很多有关设计API的优秀资源。 They recommend using OAuth 2.0 for authentication/authorization. 他们建议使用OAuth 2.0进行身份验证/授权。

Here is a description on how to use HMAC authentication to secure a Web API . 以下是如何使用HMAC身份验证来保护Web API的说明

I have used a workaround for my web application when I have had to use API's that only used an API Key. 当我不得不使用仅使用API​​密钥的API时,我已经为我的Web应用程序使用了一种解决方法。 I do not access the API directly from the client-side portion of the web application (ie JavaScript in the web browser). 我不直接从Web应用程序的客户端部分访问API(即Web浏览器中的JavaScript)。 Instead I access the API server-side and store the API Key encrypted in a secure configuration file. 相反,我访问API服务器端并将加密的API密钥存储在安全配置文件中。 I provide a Facade to the original API and use my own security methods to secure the Facade API that are dependent on the type of application. 我提供了原始API的Facade,并使用我自己的安全方法来保护依赖于应用程序类型的Facade API。

General API workflow: 一般API工作流程:

  1. client sends a request 客户端发送请求
  2. request is authenticated and authorized 请求已通过身份验证和授权
  3. data is sent back 数据被发回

Web Site - log in 网站 - 登录

  1. user logs in providing a username and password 用户登录提供用户名和密码
  2. A secret is created and stored into a coockie 创建一个秘密并存储到一个coockie中

Web site - API access 网站 - API访问

  1. client sends a request 客户端发送请求
  2. request is authenticated and authorized based on coockie's secret (coockies are sent with the request) 请求根据coockie的秘密进行身份验证和授权(随请求发送coockies)
  3. data is sent back 数据被发回

Non WEB client - obtaining an API KEY (long random alpha numeric string) 非WEB客户端 - 获取API KEY(长随机字母数字字符串)

  1. Option 1 - User registers a client on the website, gets an API KEY and stores it into the client 选项1 - 用户在网站上注册客户端,获取API KEY并将其存储到客户端
  2. Option 2 - User enters username and password into the client, the client requests an API KEY with usenamer and password, the key is returned and stored into the client. 选项2 - 用户输入用户名和密码到客户端,客户端使用usenamer和密码请求API KEY,返回密钥并存储到客户端。 Username and Password are not stored on the client. 用户名和密码不存储在客户端上。

Non WEB client - API comunication 非WEB客户端 - API通信

  1. client sends a request with API KEY 客户端使用API​​ KEY发送请求
  2. request is authenticated and authorized based on API-KEY 请求已根据API-KEY进行身份验证和授权
  3. data is sent back 数据被发回

When the key is generated with option 2 you can get some additional data since it originates from the client (operating system, browser). 当使用选项2生成密钥时,您可以获得一些额外的数据,因为它来自客户端(操作系统,浏览器)。 In this case when checking the API-KEY you can force a user to generate a new one if, he changed OS or Browser 在这种情况下,当检查API-KEY时,如果他更改了操作系统或浏览器,则可以强制用户生成新的API

The key point is that your API authenticates requests in two ways. 关键是您的API以两种方式验证请求。 Using coockie's secret or an API KEY. 使用coockie的秘密或API KEY。 Therefore there is no need to expose the API-KEY on the website. 因此,无需在网站上公开API-KEY。

Note that for clients using an API-KEY there is no session involved. 请注意,对于使用API​​-KEY的客户端,不涉及任何会话。 Each request is authenticated only by the API-KEY. 每个请求仅通过API-KEY进行身份验证。 So those clients are considered non WEB app. 所以这些客户端被认为是非WEB应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM