我正在设计一个JSON Web API,并希望通过唯一ID来区分客户端,以便监控使用情况并阻止恶意/行为不端的客户端。 API不是封装在JavaScript库中,也不是Web应用程序独有的,任何客户端类型都可以使用它(桌面,电话等)。
问题是,网络应用程序(官方网站)也是API本身的客户端,因此必须公开其API密钥。因此,某些用户可以从页面上的JavaScript中提取密钥并使用它,而不是生成自己的密钥。
是否有可能通过一些更好/更聪明的设计选择以某种方式缓解这个问题,或者我是否必须忍受这样一个事实:恶意使用API的人可以利用这个?
我可以100%控制前端应用程序(EmberJS)和后端服务器(Go),因此可以建议任何更改。
注意:问题不是身份验证或安全性本身,而是如何要求第三方用户另外使用API密钥(!)进行身份验证!
答案 0 :(得分:6)
您应该区分Web和非Web客户端。 Web的访问密钥不能在非Web中使用,反之亦然。对于Web客户端,您可以进行引用检查等。您还可以为应用程序动态创建访问密钥,并每天(或每个会话)自动更改它们。您也可以仅为自己的应用添加一些特殊验证,例如:一些额外的密钥,由混淆的JS进行计算。
没有什么可以阻止恶意用户模仿浏览器,执行JS,操纵它,然后做坏事 - 但是你可以让它烦人,以至于他们认为不值得他们努力。 权限等非常重要的内容显然需要在服务器端进行检查,因此滥用您的API不应该是一个大问题。您必须通过网站的API密钥处理API滥用,如同您使用常规的网络应用滥用 - IP阻止等。
您仍然需要保密非Web客户端的API密钥。这只能通过混淆不可靠地完成,您可以将其留在客户端开发人员手中。如果他们的密钥被泄露和滥用,你撤销它,他们将有动力解决它。
看看OAuth 2.0,它们会阻止许多可能对您有用的功能。即使你不想使用它,你也可以从中获得灵感。 OpenStreetMap使用OAuth(不确定是1还是2)作为基于flash的编辑器;只要登录用户从同一来源调用,OAuth权限授予就会自动完成。对于第三方应用,用户需要手动执行此操作。你可能想检查一下。
答案 1 :(得分:4)
只使用一个API密钥,您将无法保证API的安全。您描述的API密钥基本上是一个公钥,您需要某种类型的私钥来进行安全识别/身份验证,并提供一种机制来提供它。
你问过Twitter是如何解决这个问题的。他们使用Oath 1.0a。以下简要介绍了如何将其与Twitter Developer FAQ。
中的API密钥绑定大多数与API的集成都需要您识别您的 通过API密钥向Twitter申请。在Twitter平台上, 术语“API密钥”通常指的是所谓的OAuth使用者 键。此字符串在发出请求时标识您的应用程序 API。在OAuth 1.0a中,您的“API密钥”可能指的是组合 这个消费者密钥和“消费者秘密”,一个曾经的字符串 安全地“签署”您对Twitter的请求。大多数要求Twitter 除了应用程序上下文之外,还需要用户上下文。用户 通过使用另一种令牌/密钥来呈现上下文 称为“访问令牌”。有关更多信息,请参阅获取访问令牌 信息。
您可以在Apigee.com找到有关设计API的大量资源。他们建议使用OAuth 2.0进行身份验证/授权。
以下是有关如何使用HMAC authentication to secure a Web API的说明。
当我不得不使用仅使用API密钥的API时,我已经为我的Web应用程序使用了一种解决方法。我不直接从Web应用程序的客户端部分(即Web浏览器中的JavaScript)访问API。相反,我访问API服务器端并将加密的API密钥存储在安全配置文件中。我提供了原始API的Facade,并使用我自己的安全方法来保护依赖于应用程序类型的Facade API。
答案 2 :(得分:-2)
常规API工作流程:
网站 - 登录
网站 - API访问
非WEB客户端 - 获取API KEY(长随机字母数字字符串)
非WEB客户端 - API通信
当使用选项2生成密钥时,您可以获得一些额外的数据,因为它来自客户端(操作系统,浏览器)。在这种情况下,当检查API-KEY时,如果他更改了操作系统或浏览器,则可以强制用户生成新的
关键是您的API以两种方式验证请求。 使用coockie的秘密或API KEY。因此,无需在网站上公开API-KEY。
请注意,对于使用API-KEY的客户端,不涉及任何会话。每个请求仅通过API-KEY进行身份验证。所以这些客户端被认为是非WEB应用程序。