目标: 允许用户通过Facebook认证进入iOS应用程序,这需要访问我正在运行的受保护的web服务。

假设: 对于那些选择不使用Facebook登录的用户,有一个本地认证(和注册)系统。

细节:

假设我们希望为用户提供一种选择,让用户无需为我们的系统创建单独的帐户/凭据就可以登录Facebook。 因为我们支持自己的本地身份验证机制(用户名和密码),所以我们有自己的用户id,并发出一个身份验证令牌,该令牌在初始凭证验证之后用于后续交互。

我很惊讶Facebook在他们的开发者文档中没有这方面的最佳实践。所有现有的文档都假设你正在将facebook认证构建到一个网站中,或者是一个不需要认证服务的独立移动应用程序。

以下是我对这将如何设计的最初想法,但希望验证它是否正确。

Client pops the Facebook iOS Login UI User signs in with Facebook credentials and gets access token iOS App passes access token to our server Our server talks to FB graph API using access token to (a) validate the token and (b) get the FB user ID for that access token. e.g. Our server would call https://graph.facebook.com/me/?access_token=XYZ which would return profile info in a JSON object Assuming it's valid, our server extracts the User ID from the JSON object and checks whether the user already has an account. If so, we issue our own auth ticket to client to use for that session. If user doesn't have an account, we create a new one with the Facebook User ID, assign our own unique UserID and issue our auth ticket. Client then passes auth ticket back on subsequent interactions that need authentication.

这对我来说似乎是正确的方法,但不确定我是否错过了一些疯狂的基本内容,走上了错误的(复杂的)道路。


我自己也刚处理过,这是让我很难受的部分:

在你的第五步中…用户可以在你这里注册一个完全独立于他们的Facebook账号,对吧?然后在其他时间登录Facebook....你刚给他们创建了第二个账户,却把第一个账户弄丢了。

需要有一种方法来登录到您的web服务,然后登录到facebook,并捕获facebook ID和本地帐户之间的关联。

除此之外,你的计划听起来很可靠。

更新:Facebook在这里添加了一份文件,概述了这种情况

我可以看到这个策略的一个问题是,有人可以给你一个不同的facebook应用程序的访问令牌。据我所知,没有办法验证访问令牌是否适合你的应用程序,所以你只是继续使用它。

不过,这听起来并不是很有害。一般来说,人们/应用程序试图保护访问令牌,而不是共享它们。

一个可能的利用是,让某人创建他们自己的网站或移动应用程序,为他们的用户获取访问令牌,并尝试使用您的API对他们进行身份验证。如果此操作成功(用户在您的站点中拥有facebook帐户),恶意站点将能够使用您的API冒充该用户。

虽然可能性不大,但我认为可行。

编辑:看起来有一种方法可以验证访问令牌。从用户访问令牌获取应用程序id(或验证源应用程序的令牌)。

使用https传输认证令牌到您的服务器,如Facebook所述

共享访问令牌 我们的数据政策明确禁止任何访问令牌的共享 但是,我们允许开发者这样做 在本机实现和服务器之间共享令牌 实现相同的应用程序(即。使用相同的App ID),只要 传输使用HTTPS进行。

你的解决办法完全有效。

Maybe an alternative: why not just get the email on the client from the initial social service request and send to your web service? The web service could just store the email, and maybe a social_provider as well. I understand that your web service will not be able to validate where the email came from, but isn't there a high-trust relationship between your web service and your client? If there is, seems like you can depend on the email coming from the right place. Someone please let me know what obvious thing I'm missing that makes the email-based approach silly...