json 简单、安全的 API 认证系统
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/846752/
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
Simple, secure API authentication system
提问by
I have a simple REST JSON API for other websites/apps to access some of my website's database (through a PHP gateway). Basically the service works like this: call example.com/fruit/orange, server returns JSON information about the orange. Here is the problem: I only want websites I permit to access this service. With a simple API key system, any website could quickly attain a key by copying the key from an authorized website's (potentially) client side code. I have looked at OAuth, but it seems a little complicated for what I am doing. Solutions?
我有一个简单的 REST JSON API 供其他网站/应用程序访问我网站的一些数据库(通过 PHP 网关)。基本上服务是这样工作的:调用example.com/fruit/orange,服务器返回关于橙子的JSON信息。问题是:我只想要我允许访问此服务的网站。使用简单的 API 密钥系统,任何网站都可以通过从授权网站的(潜在)客户端代码复制密钥来快速获取密钥。我看过 OAuth,但对于我正在做的事情来说似乎有点复杂。解决方案?
回答by Chris Harris
You should use OAuth.
您应该使用 OAuth。
There are actually two OAuth specifications, the 3-legged version and the 2-legged version. The 3-legged version is the one that gets most of the attention, and it's notthe one you want to use.
实际上有两个 OAuth 规范,3-legged 版本和 2-legged 版本。三足版是最受关注的,不是你想用的。
The good news is that the 2-legged version does exactly what you want, it allows an application to grant access to another via either a shared secret key (very similar to Amazon's Web Service model, you will use the HMAC-SHA1 signing method) or via a public/private key system (use signing method: RSA-SHA1). The bad news, is that it's not nearly as well supported yet as the 3-legged version yet, so you may have to do a bit more work than you otherwise might have to right now.
好消息是 2-legged 版本完全符合您的要求,它允许应用程序通过共享密钥授予另一个访问权限(与亚马逊的 Web 服务模型非常相似,您将使用 HMAC-SHA1 签名方法)或通过公钥/私钥系统(使用签名方法:RSA-SHA1)。坏消息是,它的支持还没有 3 腿版本那么好,所以你可能需要做比现在更多的工作。
Basically, 2-legged OAuth just specifies a way to "sign" (compute a hash over) several fields which include the current date, a random number called "nonce," and the parameters of your request. This makes it very hardto impersonate requests to your web service.
基本上,2-legged OAuth 只是指定了一种“签名”(计算散列)几个字段的方法,这些字段包括当前日期、称为“nonce”的随机数和您的请求参数。这使得模拟对您的 Web 服务的请求变得非常困难。
OAuth is slowly but surely becoming an accepted standard for this kind of thing -- you'll be best off in the long run if you embrace it because people can then leverage the various libraries available for doing that.
OAuth 正在缓慢但肯定地成为这种事情的公认标准——从长远来看,如果你接受它,你将是最好的,因为人们可以利用各种可用的库来做到这一点。
It's more elaborate than you would initially want to get into - but the good news is that a lot of people have spent a lot of time on it so you know you haven't forgotten anything. A great example is that very recently Twitter found a gap in the OAuth security which the community is currently working on closing. If you'd invented your own system, you're having to figure out all this stuff on your own.
它比您最初想要的要复杂得多 - 但好消息是很多人已经花了很多时间在它上面,所以您知道自己没有忘记任何事情。一个很好的例子是,最近 Twitter 发现 OAuth 安全性中的一个漏洞,社区目前正在努力解决这个漏洞。如果您发明了自己的系统,则必须自己解决所有这些问题。
Good luck!
祝你好运!
Chris
克里斯
回答by Daniel Magnusson
OAuth is not the solution here.
OAuth is when you have endusers and want 3rd party apps not to handle end user passwords. When to use OAuth:
http://blog.apigee.com/detail/when_to_use_oauth/
OAuth 不是这里的解决方案。
OAuth 是当您有最终用户并希望 3rd 方应用程序不处理最终用户密码时。何时使用 OAuth:http:
//blog.apigee.com/detail/when_to_use_oauth/
Go for simple api-key.
And take additional measures if there is a need for a more secure solution.
选择简单的 api-key。
如果需要更安全的解决方案,请采取其他措施。
Here is some more info, http://blog.apigee.com/detail/do_you_need_api_keys_api_identity_vs._authorization/
这里有更多信息,http://blog.apigee.com/detail/do_you_need_api_keys_api_identity_vs._authorization/
回答by Kekoa
If someone's client side code is compromised, they should get a new key. There's not much you can do if their code is exposed.
如果某人的客户端代码被泄露,他们应该获得一个新密钥。如果他们的代码暴露了,你就无能为力了。
You can however, be more strict by requiring IP addresses of authorized servers to be registered in your system for the given key. This adds an extra step and may be overkill.
但是,您可以更严格地要求在您的系统中为给定密钥注册授权服务器的 IP 地址。这增加了一个额外的步骤,可能是矫枉过正。
I'm not sure what you mean by using a "simple API key" but you should be using some kind of authentication that has private keys(known only to client and server), and then perform some kind of checksum algorithm on the data to ensure that the client is indeed who you think it is, and that the data has not been modified in transit. Amazon AWSis a great example of how to do this.
我不确定使用“简单 API 密钥”是什么意思,但您应该使用某种具有私钥的身份验证(仅客户端和服务器知道),然后对数据执行某种校验和算法以确保客户确实是您认为的那个人,并且数据在传输过程中没有被修改。 亚马逊 AWS就是一个很好的例子,说明如何做到这一点。
I think it may be a little strict to guarantee that code has not been compromised on your clients' side. I think it is reasonable to place responsibility on your clients for the security of their own data. Of course this assumes that an attacker can only mess up that client's account.
我认为保证代码没有在您的客户方面受到损害可能有点严格。我认为让您的客户承担自己数据安全的责任是合理的。当然,这是假设攻击者只能弄乱该客户的帐户。
Perhaps you could keep a log of what ip requests are coming from for a particular account, and if a new ip comes along, flag the account, send an email to the client, and ask them to authorize that ip. I don't know maybe something like that could work.
也许您可以记录特定帐户的 ip 请求来自哪些日志,如果出现新 ip,则标记该帐户,向客户端发送电子邮件,并要求他们授权该 ip。我不知道这样的事情是否可行。
回答by Kim L
Basically you have two options, either restrict access by IP or then have an API key, both options have their positive and negative sides.
基本上你有两个选择,要么限制通过 IP 访问,要么拥有一个 API 密钥,这两个选项都有积极和消极的一面。
Restriction by IP
This can be a handy way to restrict the access to you service. You can define exactly which 3rd party services will be allowed to access your service without enforcing them to implement any special authentication features. The problem with this method is however, that if the 3rd party service is written for example entirely in JavaScript, then the IP of the incoming request won't be the 3rd party service's server IP, but the user's IP, as the request is made by the user's browser and not the server. Using IP restriction will hence make it impossible to write client-driven applications and forces all the requests go through the server with proper access rights. Remember that IP addresses can also be spoofed.
IP 限制
这是一种限制对您服务的访问的便捷方式。您可以准确定义哪些 3rd 方服务将被允许访问您的服务,而无需强制它们实现任何特殊的身份验证功能。然而,这种方法的问题是,如果 3rd 方服务是完全用 JavaScript 编写的,那么传入请求的 IP 将不是 3rd 方服务的服务器 IP,而是用户的 IP,因为请求是由用户的浏览器而不是服务器。因此,使用 IP 限制将无法编写客户端驱动的应用程序,并强制所有请求通过具有适当访问权限的服务器。请记住,IP 地址也可能被欺骗。
API key
The advantage with API keys is that you do not have to maintain a list of known IPs, you do have to maintain a list of API keys, but it's easier to automatize their maintenance. Basically how this works is that you have two keys, for example a user id and a secret password. Each method request to your service should provide an authentication hash consisting of the request parameters, the user id and a hash of these values (where the secrect password is used as the hash salt). This way you can both authenticate and restrict access. The problem with this is, that once again, if the 3rd party service is written as client-driven (for example JavaScript or ActionScript), then anyone can parse out the user id and secret salt values from the code.
API 密钥 API 密钥
的优点是您不必维护已知 IP 的列表,您必须维护 API 密钥列表,但更容易将其维护自动化。基本上这是如何工作的,你有两个密钥,例如一个用户 ID 和一个秘密密码。对您的服务的每个方法请求都应提供一个身份验证哈希,其中包含请求参数、用户 ID 和这些值的哈希(其中使用安全密码作为哈希盐)。通过这种方式,您可以验证和限制访问。问题在于,如果第 3 方服务被编写为客户端驱动(例如 JavaScript 或 ActionScript),那么任何人都可以从代码中解析出用户 ID 和秘密盐值。
Basically, if you want to be sure that only the few services you've specifically defined will be allowed to access your service, then you only option is to use IP restriction and hence force them to route all requests via their servers. If you use an API key, you have no way to enforce this.
基本上,如果您想确保只允许您明确定义的少数服务访问您的服务,那么您唯一的选择是使用 IP 限制,从而强制他们通过其服务器路由所有请求。如果您使用 API 密钥,则无法强制执行此操作。
回答by Marlon
All of production of IP's security seems produces a giant bug to users before getting connected. Symbian 60s has the fullest capability to left an untraced, reliable and secure signal in the midst of multiple users(applying Opera Handler UI 6.5, Opera Mini v8 and 10) along with the coded UI's, +completely filled network set-up. Why restrict for other features when discoverable method of making faster link method is finally obtained. Keeping a more identified accounts, proper monitoring of that 'true account'-if they are on the track-compliance of paying bills and knowing if the users has an unexpired maintaining balance will create a more faster link of internet signal to popular/signatured mobile industry. Why making hard security features before getting them to the site, a visit to their accounts monthly may erase all of connectivity issues? All of the user of mobile should have no capability to 'get connected' if they have unpaid bills. Why not provide an 'ALL in One' -Registration/Application account, a programmed fixed with OS, (perhaps an e-mail account) instead with a 'monitoring capability' if they are paying or not (password issues concern-should be given to other department). And if 'not' turn-off their account exactly and their other link features. Each of them has their own interests to where to get hooked daily, if you'd locked/turn them off due to unpaid bills that may initiate them to re-subscribe and discipline them more to become a more responsible users and that may even expire an account if not maintained. Monthly monitoring or accessing of an identified 'true account' with collaboration to the network provider produces higher privacy instead of always asking for users 'name' and 'password', 'location', 'permissions' to view their data services. IP's marked already their first identity or 'finding the location of the users' so, it's seems unnessary to place it on browsers pre-searches, why not use 'Obtaining data' or 'Processing data.'
在连接之前,所有 IP 安全性的生产似乎都会给用户带来一个巨大的错误。Symbian 60s 具有最完整的能力,可以在多个用户(应用 Opera Handler UI 6.5、Opera Mini v8 和 10)以及编码的 UI 和完全填充的网络设置中留下无法追踪的、可靠和安全的信号。当最终获得可发现的更快链接方法的方法时,为什么要限制其他特征。保留更明确的账户,适当监控该“真实账户”——如果他们正在支付账单的合规性,并了解用户是否有未到期的维持余额,将创建更快的互联网信号链接到流行/签名的移动设备行业。为什么要在将它们带到站点之前制作硬安全功能,每月访问他们的帐户可能会消除所有连接问题?如果他们有未付账单,所有移动用户都应该没有能力“连接”。为什么不提供一个“一体机”-注册/应用程序帐户,一个用操作系统固定的程序,(可能是一个电子邮件帐户),而不是一个“监控功能”,如果他们支付或不支付(密码问题关注-应该给出)到其他部门)。如果“不”完全关闭他们的帐户和其他链接功能。他们每个人都有自己的兴趣,每天都去哪里上瘾,如果你因为未付账单而锁定/关闭它们,可能会促使他们重新订阅并更多地惩罚他们以成为更负责任的用户,甚至可能会过期一个帐户,如果没有维护。每月监控或访问已识别的“ 与网络提供商合作的“真实帐户”产生更高的隐私,而不是总是要求用户“姓名”和“密码”、“位置”、“权限”以查看他们的数据服务。IP 已经标记了他们的第一个身份或“查找用户的位置”,因此,将其放在浏览器预搜索中似乎是不必要的,为什么不使用“获取数据”或“处理数据”。

