iOS OAuth 认证

基本概念

  • OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准

  • OAuth 的授权不会使第三方触及到用户的帐号信息

  • OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据

  • 每一个令牌授权一个 特定的网站 在 特定的时段内 访问 特定的资源

    OAuth 授权流程图

  •  

  • 转换成我们的代码流程 
  • 转换成我们的效果

  • (A) Authorization Request (请求授权) 

  • (B) Authorization Grant (同意授权) http://www.itcast.cn/?code=5dfa8a11594dd1c1b3553bba95004963
  • (C) 截取Code

    // 1.先判断url是否有值
          if let urlString = request.URL?.absoluteString {
              //2.url有值的话,再次判断一下url是否是 http://www.itcast.cn开头
              if urlString.hasPrefix(AppRedirectUri) {
                  //3.如果是重定向的url,我们需要截获url后边的参数
                  let query = request.URL?.query
                  //4. 截获url来获得 code
                  let code = query!.substringFromIndex("code=".endIndex)
                  printLog(code)
    
                  //因为已经获取到code了,就不要让他继续跳转了
                  return false
              }
          }
    
  • (D)拿到Access Token

注册应用程序

注册应用程序

  • 注册新浪微博账号

  • 访问 http://open.weibo.com

  • 成为新浪微博开发者(个人开发者)

  • 点击 微连接 - 移动应用

填写基本信息,如下图所示:

 

加载授权页面

功能需求

通过浏览器访问新浪授权页面,获取授权码

接口文档

http://open.weibo.com/wiki/Oauth2/authorize

测试授权 URL https://api.weibo.com/oauth2/authorize?client_id=308738166&redirect_uri=http://www.itcast.cn&response_type=code

注意:回调地址必须与注册应用程序保持一致

 

ATS

<key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>


功能实现

准备工作

在Login 文件夹中 新建 HMOAuthViewController.swift 继承自 UIViewController

设置Nav

//MARK:--设置Nav
    private func setupNav(){

        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: self, action: "dismiss")
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "自动填充", style: UIBarButtonItemStyle.Plain, target: self, action: "autofill")

    }


加载 OAuth 视图控制器

加载授权页面

//设置webView的请求
        let request = NSURLRequest(URL: NSURL(string: "https://api.weibo.com/oauth2/authorize?client_id=\(client_id)&redirect_uri=\(redirect_uri)")!)
        //设置webView代理
        webView.delegate = self
        //请求页面
        webView.loadRequest(request)


  • 在 info.plist 中增加 ATS 设置 NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802

自动填充

    let jsString = "document.getElementById('userId').value='itcast123456@hotmail.com';document.getElementById('passwd').value='itcast123456'"

    webView.stringByEvaluatingJavaScriptFromString(jsString)
  • 实现代理方法,跟踪重定向 URL

    // MARK: - UIWebView 代理方法
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
     print(request)
    
     return true
    }
    

    结果分析

如果 URL 以回调地址开始,需要检查查询参数 其他 URL 均加载

  • 修改代码

      func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    
          print(request.URL?.absoluteString)
    
          /*
          Optional("https://api.weibo.com/oauth2/authorize?client_id=2219353247&redirect_uri=http://www.itcast.cn")
          Optional("https://api.weibo.com/oauth2/authorize")
          Optional("https://api.weibo.com/oauth2/authorize#")
          Optional("https://api.weibo.com/oauth2/authorize")
          Optional("http://www.itcast.cn/?code=f8bf89e940ae7f8884a892ff5af96a4b")
          Optional("about:blank")
          Optional("about:blank")
          Optional("about:blank")
          Optional("http://apisus.wueee.com/c/apisus.php?uid=1687&id=1382&url=http%3A%2F%2Findex.8cnd.com%2Ftj%2F&llurl=&thepage=http://www.itcast.cn/?code=f8bf89e940ae7f8884a892ff5af96a4b&fuck=1447318351")
          */
          // 1.先判断url是否有值
          if let urlString = request.URL?.absoluteString {
              //2.url有值的话,再次判断一下url是否是 http://www.itcast.cn开头
              if urlString.hasPrefix(AppRedirectUri) {
                  //3.如果是重定向的url,我们需要截获url后边的参数
                  let query = request.URL?.query
                  //4. 截获url来获得 code
                  let code = query!.substringFromIndex("code=".endIndex)
                  printLog(code)
                  //因为已经获取到code了,就不要让他继续跳转了
                  return false
              }
          }
    
          return true
      }
    

加载指示器

导入 SVProgressHUD import SVProgressHUD

WebView 代理方法

func webViewDidStartLoad(webView: UIWebView) {
    SVProgressHUD.show()
}

func webViewDidFinishLoad(webView: UIWebView) {
    SVProgressHUD.dismiss()
}
关闭
///  关闭
func close() {
    SVProgressHUD.dismiss()
    dismissViewControllerAnimated(true, completion: nil)
}

 

posted @ 2016-05-05 09:50  赤云西  阅读(246)  评论(0编辑  收藏  举报