基本概念
-
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/wiki/Oauth2/authorize
注意:回调地址必须与注册应用程序保持一致
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) }