Rails API 身份验证 - 健全性检查和建议
我想创建一个 Rails 应用程序,它公开一个仅由授权客户端应用程序(将是 iOS / android 的移动应用程序)使用的 API。我还没有开始开发该应用程序,但访问底层数据的主要方法是通过 API。我一直在考虑使用 grape gem,但需要为其添加身份验证层。我正在考虑使用 devise 并添加另一个模型来存储客户端详细信息、api 密钥和密钥。通过 api 登录后,将返回 api 密钥和密钥。 API 密钥会随每个请求一起传输,但秘密密钥不会。相反,它用于签署每个请求;请求参数按名称排序,使用密钥作为哈希密钥进行哈希处理。然后将该签名作为参数添加到请求中。
这个身份验证系统听起来合乎逻辑且安全吗?
我之前曾尝试对系统进行原型设计,但在使用 JSON 和 devise 注册用户时遇到了困难。起初我收到了 CSRF 错误。然后我关闭了 protected_from_forgery 并收到另一个错误。如果我以这种方式进行身份验证,关闭此功能是否安全?
I want to create a Rails application which exposes an API to be consumed by only authorised client applications (will be mobile apps for iOS / android). I've not started working on the app yet, but the primary method of accessing the underlying data will be through the api. I've been looking at using the grape gem, but would need to add an authentication layer to it. I was thinking about using devise and adding another model for storing client details, api key and secret key. Upon sign in through the api, the api key and secret are returned. The API key is transmitted with each request, but the secret key is not. Instead, it is used to sign each request; the request parameters are ordered by name, hashed using the secret key as the hash key. This signature is then added as a parameter to the request.
Does this system of authentication sound logical and secure?
I tried to prototype the system earlier, but ran into difficulty signing up a user using JSON with devise. At first I was getting a CSRF error. I then turned off protect_from_forgery and was getting another error. Is it safe to turn this off if I am authenticating in this way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,您可以关闭 Rails CSRF 保护,因为您使用的是不同的真实性方法,只要日期或时间戳始终位于正在签名的参数内即可。您可以使用它来比较请求时间与服务器时间,并确保您没有遭受重放攻击。
Yes you can turn off rails CSRF protection since you are using a different authenticity method as long as a date or timestamp is always inside the parameters that are being signed. You can use this to compare the request time to the server time and make sure you aren't undergoing a replay attack.
protect_from_forgery
帮助您保护 HTML 表单。如果您从移动客户端使用 JSON,则不需要它。如果我是您,我会执行以下操作:
在用户的帐户页面上,有一个显示“(重新)生成 API 密钥”的按钮
客户端然后将此密钥嵌入到其调用代码中并随每个请求传递。
您的 API 服务器检查此 API 密钥是否可以与此客户端 ID 一起使用。
非常容易实施并且服务良好。
签名参数也有效,我在几个项目中成功使用了它。但它增加了代码复杂性,却没有任何实际收益(密钥在客户端,攻击者已经知道)。
protect_from_forgery
helps you protect your HTML forms. If you're consuming JSON from mobile clients, you don't need it.Here's what I would do if I were you:
on user's account page, have a button that says "(re)generate API key"
client then embeds this key into his calling code and passes with each request.
your API server checks whether this API key can be used with this client id.
Very easy to implement and serves well.
Signing parameters also works and I used it in several projects with success. But it increases code complexity without any real gain (secret key is on the client, attacker already knows it).