在 iOS 应用程序中设计 Facebook 身份验证,该应用程序还可以访问安全的 Web 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4623974/
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
Design for Facebook authentication in an iOS app that also accesses a secured web service
提问by TMC
Goal:Allow a user to authentication with Facebook into an iOS application which requires access to a protected web service that I'm running.
目标:允许用户在需要访问我正在运行的受保护 Web 服务的 iOS 应用程序中使用 Facebook 进行身份验证。
Assumptions:There is a native authentication (and registration) system in place for those users that opt not to use Facebook for sign in.
假设:对于那些选择不使用 Facebook 登录的用户,有一个本地身份验证(和注册)系统。
Details:
细节:
- Assume we want to offer the option for a user to sign in with Facebook without creating a separate account/credential for our system.
- Because we support our own native auth mechanism (username and password) we have our own user IDs and issue an authentication token that is used for subsequent interactions after the initial credential validation.
- 假设我们希望为用户提供使用 Facebook 登录的选项,而无需为我们的系统创建单独的帐户/凭据。
- 因为我们支持自己的本地身份验证机制(用户名和密码),所以我们拥有自己的用户 ID 并发出身份验证令牌,用于初始凭据验证后的后续交互。
I'm surprised that Facebook doesn't have best practices for this in their developer documentation. All the existing documentation is either assuming you are building FB auth into a website, or a standalone mobile app with no service that requires authentication.
我很惊讶 Facebook 在他们的开发人员文档中没有这方面的最佳实践。所有现有的文档要么假设您正在将 FB 身份验证构建到网站中,要么是一个没有需要身份验证的服务的独立移动应用程序。
Here's my initial thoughts on how this would be designed but want validation on whether it's correct.
这是我对如何设计的初步想法,但希望验证它是否正确。
- 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=XYZwhich 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 iOS 登录
- UI 用户使用 Facebook 凭据登录并获取访问令牌
- iOS 应用程序将访问令牌传递给我们的服务器
我们的服务器使用访问令牌与 FB 图形 API 对话,以 (a) 验证令牌和 (b) 获取该访问令牌的 FB 用户 ID。
例如,我们的服务器会调用https://graph.facebook.com/me/?access_token=XYZ,它会在 JSON 对象中返回个人资料信息
假设它是有效的,我们的服务器从 JSON 对象中提取用户 ID 并检查用户是否已经有一个帐户。如果是这样,我们向客户端发出我们自己的身份验证票以用于该会话。如果用户没有帐户,我们会使用 Facebook 用户 ID 创建一个新帐户,分配我们自己的唯一用户 ID 并发出我们的身份验证票。
- 客户端然后在需要身份验证的后续交互中传回身份验证票证。
This seems like the right approach to me but not sure if I'm missing something insanely basic and going down the wrong (complicated) path.
这对我来说似乎是正确的方法,但不确定我是否遗漏了一些非常基本的东西并且走上了错误(复杂)的道路。
采纳答案by Dan Ray
I just dealt with this myself, and here's the part that bit me:
我只是自己处理了这个问题,这里是咬我的部分:
In your step 5... It's possible for a user to register for an account with you entirely separate from their Facebook ID, right? Then some other time they log in with Facebook.... And you just created them a second account and lost their first one.
在您的第 5 步中……用户可以在您的帐户中注册完全独立于他们的 Facebook ID 的帐户,对吗?然后其他时候他们用 Facebook 登录……而你刚刚为他们创建了第二个帐户,却丢失了他们的第一个帐户。
There needs to be a way to be logged in to your web service, then log in to facebook, and capture the association between the facebook ID and the local account.
需要有一种方式登录到你的web服务,然后登录facebook,并捕获facebook ID和本地帐户之间的关联。
Apart from that, your plan sounds solid.
除此之外,你的计划听起来很可靠。
Update: Facebook has added a doc outlining such a scenario HERE
更新:Facebook 已经添加了一个文档,在此处概述了这种情况
回答by zoomcrypt
Use https to transmit the auth token to your server, as stated by Facebook
如 Facebook 所述,使用 https 将身份验证令牌传输到您的服务器
Sharing of Access Tokens
Our Data Policies explicitly prohibit any sharing of an Access Token for your app with any other app. However, we do allow developers to share Tokens between a native implementation and a server implementation of the same App (ie. using the same App ID) as long as the transfer takes place using HTTPS.
共享访问令牌
我们的数据政策明确禁止与任何其他应用程序共享您的应用程序的访问令牌。但是,我们确实允许开发人员在同一应用程序的本机实现和服务器实现之间共享令牌(即使用相同的 App ID),只要使用 HTTPS 进行传输即可。
回答by ivant
One problem I can see with this strategy, is that somebody can give you an access token obtained for a different facebook app. As far as I know, there's no way to verify that the access token is for your application, so you'll just go on and use it.
我可以看到这个策略的一个问题是,有人可以给你一个为不同的 facebook 应用程序获得的访问令牌。据我所知,无法验证访问令牌是否适用于您的应用程序,因此您只需继续使用它即可。
It doesn't sound very harmful, though. Generally people/apps try to protect the access tokens, rather than sharing them.
不过,这听起来并不是很有害。通常,人们/应用程序会尝试保护访问令牌,而不是共享它们。
One possible exploit of this would be, for somebody to create their own site or mobile app, obtain access tokens for their users and try to authenticate them, using your API. If this succeeds (the user is has a facebook account in your site), the malicious site will be able to use your API impersonating the user.
一种可能的利用是,让某人创建自己的网站或移动应用程序,为其用户获取访问令牌并尝试使用您的 API 对其进行身份验证。如果此操作成功(用户在您的站点中拥有 facebook 帐户),恶意站点将能够使用您的 API 来冒充用户。
It's a bit of a long shot, but I think it could work.
这有点远,但我认为它可以工作。
Edit: It looks like there is a way to validate the access token after all. See the answer by @Daaniel on question Get application id from user access token (or verify the source application for a token).
编辑:看来毕竟有一种方法可以验证访问令牌。请参阅@Daaniel 对问题Get application id from user access token (or verify the source application for a token)的回答。
回答by hamsterdam
your solution totally works.
您的解决方案完全有效。
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...
也许另一种选择:为什么不从最初的社交服务请求中获取客户端上的电子邮件并将其发送到您的 Web 服务?Web 服务可以只存储电子邮件,也可以存储 social_provider。我知道您的 Web 服务将无法验证电子邮件的来源,但是您的 Web 服务与您的客户之间是否存在高度信任的关系?如果有,似乎您可以依赖来自正确位置的电子邮件。有人请让我知道我遗漏了什么明显的东西使基于电子邮件的方法变得愚蠢......