使用 Facebook OAuth 保护 Rest API 端点的可能方法 [英] Possible approach to secure a Rest API endpoints using Facebook OAuth
问题描述
我一直在阅读有关该主题的大量内容,但我发现的只是过时或部分答案,这些答案并没有真正帮助我,实际上只是让我更加困惑.我正在编写一个由 Web 应用程序(托管在与 API 相同的域上)和一个 Android 应用程序访问的 Rest API(Node+Express+MongoDB).
I've been reading a lot about the topic but all I find are obsolete or partial answers, which don't really help me that much and actually just confused me more. I'm writing a Rest API (Node+Express+MongoDB) that is accessed by a web app (hosted on the same domain than the API) and an Android app.
我希望 API 只能由我的应用程序和授权用户访问.我还希望用户能够仅使用他们的 Facebook 帐户注册和登录,并且我需要能够访问一些基本信息,例如姓名、个人资料图片和电子邮件.
I want the API to be accessed only by my applications and only by authorized users. I also want the users to be able to signup and login only using their Facebook account, and I need to be able to access some basic info like name, profile pic and email.
我想到的一种可能的情况是:
A possible scenario that I have in mind is:
- 用户使用 Facebook 登录 Web 应用程序,该应用程序被授予访问用户 Facebook 信息的权限并收到访问令牌.
- 网络应用要求 API 确认此用户实际上已在我们的系统上注册,发送电子邮件和Facebook 收到的令牌.
- API 验证用户存在,它将用户名、令牌和时间戳,然后返回到客户端应用.
- 每次客户端应用程序命中 API 端点之一,它将必须提供用户名和令牌,不包括其他信息.
- 每次使用 API验证提供的用户名/令牌对匹配最多最近存储到数据库中的用户名/令牌对(使用时间戳订购),并且自我们存储以来不超过 1 小时这些信息(再次使用时间戳).如果是这种情况,API将处理请求,否则将发出 401 Unauthorized响应.
这有意义吗?这种方法是否有任何我遗漏的宏观安全漏洞?我发现使用 MongoDB 来存储这些信息的一个问题是,集合很快就会因旧令牌而变得臃肿.从这个意义上讲,我认为最好使用 Redis 的过期策略为 1 小时,以便 Redis 自动删除旧信息.
Does this make sense? Does this approach have any macroscopic security hole that I'm missing? One problem I see using MongoDB to store these info is that the collection will quickly become bloated with old tokens. In this sense I think it would be best to use Redis with an expire policy of 1 hour so that old info will be automatically removed by Redis.
推荐答案
我认为更好的解决方案是:
I think the better solution would be this:
- 通过 Facebook 登录
- 将 Facebook AccessToken 传递到服务器(通过 SSL 用于android 应用程序,对于 Web 应用程序,只需将其重定向到 API 端点FB登录后)
- 检查给定的
fb_access_token
,确保其有效.获取user_id
,email
并与现有用户交叉引用看看是新的还是旧的. - 现在,创建一个随机的、单独的
api_access_token
,您可以将其返回给 web 应用程序和 android 应用程序.如果您需要 Facebook除了登录以外的任何东西,存储fb_access_token
并在您的DB 将其与新的api_access_token
和您的user_id
相关联. - 对于此后的每次调用,发送
api_access_token
以对其进行验证.如果您需要fb_access_token
以获取更多信息,您可以通过从数据库中检索它来实现.
- Login via Facebook
- Pass the Facebook AccessToken to the server (over SSL for the android app, and for the web app just have it redirect to an API endpoint after FB login)
- Check the
fb_access_token
given, make sure its valid. Getuser_id
,email
and cross-reference this with existing users to see if its a new or old one. - Now, create a random, separate
api_access_token
that you give back to the webapp and android app. If you need Facebook for anything other than login, store thatfb_access_token
and in your DB associate it with the newapi_access_token
and youruser_id
. - For every call hereafter, send
api_access_token
to authenticate it. If you need thefb_access_token
for getting more info, you can do so by retrieving it from the DB.
总结:尽可能避免传递fb_access_token
.如果 api_access_token
遭到破坏,您可以更好地控制查看攻击者是谁、他们在做什么等,而不是他们获得 fb_access_token
.您还可以更好地控制设置到期日期、扩展 fb_access_token
s 等
In summary: Whenever you can, avoid passing the fb_access_token
. If the api_access_token
is compromised, you have more control to see who the attacker is, what they're doing etc than if they were to get ahold of the fb_access_token
. You also have more control over settings an expiration date, extending fb_access_token
s, etc
只要确保每当您通过 HTTP 传递任何类型的 access_token 时,都使用 SSL.
Just make sure whenever you pass a access_token of any sort via HTTP, use SSL.
这篇关于使用 Facebook OAuth 保护 Rest API 端点的可能方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!