iOS App 中 OAuth 授权的实现方式

iOS App 中 OAuth 授权的实现方式

在 iOS App 中,需要绑定微博、Twitter、Flickr 等第三方平台账号时,一般用 OAuth 授权的方式。OAuth 1.0 授权大致分为以下三步:

  1. 客户端向平台申请一个 request token,该 token 是未授权的;
  2. 客户端打开平台提供的登陆页面,引导用户输入用户名密码,对 request token 进行授权。登陆页面的 url 中会附带一个 redirect_url,当授权成功后会重定向到这个地址,返回客户端。
  3. 客户端拿着已授权的 request token 向平台换取一个 access token,后续就使用 access token 访问平台提供资源。

OAuth 2.0 授权的流程与 1.0 有所变化,但 2、3 两步还是存在的。关键就是其中的第二步,用户是在平台而不是客户端提供的页面上输入用户名密码,例如淘宝绑定新浪微博的页面,域名是新浪的:

OAuth 保证了客户端始终接触不到用户名密码,这样就保证了用户账号的安全,OAuth 发明的意义就在这里。一旦发现客户端做坏事,只需禁用相应的 access token 即可,不用担心自己的密码泄漏。

Web App 下第二步的登陆流程,一般会在打开的新窗口中进行。但在 iOS App 里,授权登陆的实现形式就可以有以下三种形式:

内嵌 WebView

这种方法是在 App 内置的 WebView 里打开登陆页面完成授权,例如新版 Instagram 绑定新浪微博 (下图),Path 绑定 Twitter 等。

许多平台提供的 SDK 都实现了这个流程,例如 sinaweiboios 使用一个嵌入 WebView 的 modal ViewController,而人人网 SDK 则可以选择弹出浮出层或者 push NavigationController 来显示登陆窗口。

不用 SDK 的话自己实现也不难,需要在合适的地方放一个 WebView 打开登陆页面。关键是要设置这个 WebView 的 delegate,实现 delegate 的 webView:shouldStartLoadWithRequest:navigationType: 方法,在里面检查目标 URL 是否等于 callback redirect_url,若相等则说明授权成功,关闭 WebView 即可。

这种实现方式存在以下两个明显的缺点:

  1. 由于登陆页面是嵌入在 WebView 里的,用户无法判断这个页面是由平台提供的,还是 App 伪造的,丧失了 OAuth 的最大优势,用户的密码安全得不到保障;
  2. 不同的 App 需要向同一个平台授权时,用户需要反复输入用户名密码。跟第一点相比,这点用户体验的损伤真不算什么。

切换到 Safari 进程

这种方法是切换到 Safari 进程,打开登陆页面,完成授权后再切换到 App 进程中。例如 Instagram 绑定 Flickr,甚至 Flickr App 登陆到自己的账户都是用这种方式实现的。

实现这种方法,能切换成功的关键在于 App 需要注册自己的 URL scheme,并用一个符合此 scheme 的 URL 作为授权完毕的回调地址,这样浏览器打开回调地址时就能返回 App。例如我们的全国空气污染指数的 url scheme 是 dirtybeijing,授权完成的回调地址就是 dirtybeijing://sns_authorized/weibo。在 app delegate 中实现 application:openURL:sourceApplication:annotation: (iOS ≥ 4.2) 或者 application:handleOpenURL: (iOS < 4.2)即可捕获通过 URL scheme 打开 App 的事件,从而完成 OAuth 授权的后续流程。

相比内嵌 WebView,这种方法的优点:

  1. 登陆页面通过操作系统浏览器打开,用户可以通过检查地址栏中的域名,以及是否使用了 https 来确认登陆页面不是第三方 App 伪造的;
  2. 同一个账号多次授权不同的 App 时,可以共享浏览器 cookie,使得后续的授权不需要再输入用户名密码。

当然,这种方法也有其自身的缺点:

  1. 兼容性: 由于依赖 iOS 多任务切换,所以一般只能用于 4.0 以后的操作系统。iOS 4.0 之前不支持多任务,所以 App 需要在切换到 Safari 之前自行保存现场,在从 Safari 返回以后再自行恢复现场,实现比较复杂。
  2. 多任务切换,会给用户一种流程中断的感觉。
  3. 会在 Safari 中留下一个未关闭的 tab。

腾讯微博的授权页面上,就指出了必须用这种方法完成授权,禁止使用内嵌的方法。不过大多数开发者貌似没怎么严格执行,腾讯的审核也不严格。

切换到官方应用进程

跟上一种方法类似,只不过将 Safari 替换成了平台的官方应用,最典型的就是 Facebook。由于用户已经在平台的官方 App 中登陆过,所以授权过程不需要再输入用户名密码,也不会在 Safari 中留下未关闭的 tab,在保证安全性的前提下体验是最好的。但限制也很明显:需要官方应用支持、需要用户已安装过官方应用。

Facebook SDK 中的授权过程,首先尝试使用官方 App,若未安装 Facebook App 或者操作系统不支持多任务,则会打开 Safari 完成授权;若 Safari 仍然打开失败,则会在嵌入的 WebView 打开登陆页面。完整实现可参考 Facebook.m 中的authorizeWithFBAppAuth:safariAuth: 方法。

总之,建议 App 开发者需要实现 OAuth 授权时,为保证安全性,尽量使用切换到 Safari 或者官方应用的方式进行。用户在使用 App 时,若第三方账号的登陆界面是 app 内嵌的,一定要小心。类似下图这种绑定形式太吓人了,直接向一个 App 透露微博的用户名密码,用着实在不放心。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值