专业java、php、iOS、C++、网页设计、平面设计、网络营销、游戏开发、前端与移动开发培训机构

加载授权页面获取Code

  • 通过WebView访问新浪授权页面,获取授权码
  • 接口文档http://open.weibo.com/wiki/Oauth2/authorize

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

功能实现

准备工作

  • 新建 OAuth 文件夹
  • 新建 HMOAuthViewController.swift 继承自 UIViewController

加载 OAuth 视图控制器

  • 修改 HMBaseViewController 中用户登录部分代码

    /// 登录事件
    func vistorViewLogin() {
      let oauthVC = HMOauthViewController()
    
      present(UINavigationController(rootViewController: oauthVC), animated: true, completion: nil)
    }
    
  • 新建 HMConst.swift 来存放常量.
    import UIKit
    // 默认背景颜色
    let defaultBackground = UIColor.white
    // Oauth相关
    let client_id = "1466447689"
    let client_secret = "cb092dae440c9b78eeb8282055baa0f0"
    let redirect_uri = "http://www.baidu.com/"
    
  • HMOauthViewController 中添加以下代码

    class HMOauthViewController: UIViewController {
    
      // 懒加载 webView
      lazy var webView = UIWebView()
    
      // 将控制器的View设置为webView
      override func loadView() {
          view = webView
      }
    
      func close() -> Void {
          self.dismiss(animated: true, completion: nil)
      }
    
      override func viewDidLoad() {
          super.viewDidLoad()
    
          title = "新浪微博"
          setupNavigaitonBar()
    
          /// 获取oauth授权的登录界面地址
          let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(client_id)&redirect_uri=\(redirect_uri)"
          let url = URL(string: urlString)
    
          // 加载授权登录界面
          let request = URLRequest(url: url!)
          webView.loadRequest(request)
      }
    
      /// 设置导航栏
      private func setupNavigaitonBar() {
          self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "填充", style: UIBarButtonItemStyle.plain, target: self, action: #selector(autoFill))
          self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "取消", style: UIBarButtonItemStyle.plain, target: self, action: #selector(close))
    
          // title
          self.navigationItem.title = "登录"
      }
    
      // MARK: - 按钮点击事件
      func close() -> Void {
    
      }
    
      /// 自动填充账号和密码
      @objc private func autoFill() {
    
      }
    }
    

拦截 取消和授权按钮

  • 实现代理方法,跟踪重定向 URL

    extension HMOauthViewController: UIWebViewDelegate {
      /// webView是否加载某个URL,return true表示加载, return false不加载
      func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
          // 获取webView要加载的地址
          let urlString = request.url?.absoluteString
    
          print("request = %@", urlString)
    
          return true
      }
    }
    

    输出加载 URL 结果

  • 点击取消授权,加载: http://www.baidu.com/?error_uri=%2Foauth2%2Fauthorize&error=access_denied&error_description=user%20denied%20your%20request.&error_code=21330

  • 点击授权,加载: http://www.baidu.com/?code=9a854bfa76a725689c7ff59961b0cc04

结果分析

  • 用户点击取消授权 都会加载授权回调页(http://gz.itcast.cn)
    • 点击授权 后参数里会带有?code=9a854bfa76a725689c7ff59961b0cc04

实现点击 取消授权 功能

  • 导入 SVProgressHUD
    import SVProgressHUD
    
  • 实现 WebView 代理方法

    • 显示开始加载提示
      // 加载授权登录界面
      let request = URLRequest(url: url!)
      webView.loadRequest(request)
      SVProgressHUD.show(withStatus: "正在加载登录界面...")
      
    • 加载完成时取消提示
      // webView加载网页完成
      func webViewDidFinishLoad(_ webView: UIWebView) {
        SVProgressHUD.dismiss()
      }
      
    • 拦截 URL 是否要加载

      /// webView是否加载某个URL,return true表示加载, return false不加载
      func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        // 获取webView要加载的地址
        let urlString = request.url!.absoluteString
        print("request = \(urlString)")
      
        // 如果加载的不是授权回调页面,直接加载网页,
        // 如果加载的是授权回调页面,对后面的参数进行判断,如果有code=表示点击了授权按钮,否则点击取消
      
        // 判断是否是回调地址
        if !urlString.hasPrefix(redirect_uri) {
            return true
        } else {
      
            print("回调地址: \(urlString)")
      
            // 判断后面是否跟有参数
            if let query = request.url!.query {
                let nsQuery = query as NSString
                let codeString = "code="
                // 判断query里面是否包含code=字符串
                if nsQuery.hasPrefix(codeString) {
                    let code = nsQuery.substring(from: codeString.characters.count)
                    print("拦截到code = \(code)")
                } else {    //点击取消
                    close()
                }
            }
      
            return false
        }
      }
      
    • 控制器 关闭 方法
      /// 关闭授权页面,需要取消HUD,因为有时候HUD还在显示时dismissViewControllerAnimated,会在首页上看到HUD
      func close() -> Void {
        SVProgressHUD.dismiss()
        self.dismiss(animated: true, completion: nil)
      }
      

results matching ""

    No results matching ""