Swift 的 新浪微博 OAuth 认证实现

2018-02-27 11:06:36来源:https://didee.cn/2016/11/29/Swift-Weibo-OAuth/作者:Conver人点击

分享

Alamofire


SwiftyJSON
封装网络请求

import UIKit
import Alamofire
import SwiftyJSON
class HTTPTool{
static let shared = HTTPTool()
}
extension HTTPTool {
/// 网络请求方法
///
/// - Parameters:
/// - url: url
/// - method: method
/// - params: params
/// - success: 请求成功: 返回SwiftyJSON对象(可直接取子对象)
/// - errors: errors
func requestWithParameters(url: String, method: HTTPMethod, parameters params: Parameters, success: @escaping (_ json: JSON)->Void, errors: @escaping ()->Void) {
Alamofire.request(url, method: method, parameters: params).responseJSON { (response) in
switch response.result {
case .success:
if let value = response.result.value{
let json = JSON(value)
guard json["_error"].string == nil else{
errors()
return
}
success(json)
}
break
case .failure(let error):
NSLog("error,failure: /(error)")
errors()
break
}
}
}
}


OAuth认证
WebView加载授权网页
OAuth2的authorize接口


获取URL

定义 client_id 和 redirect_uri 为常量



fileprivate let client_id = ""
fileprivate let redirect_uri = ""


拼接URL



var oAuthURL:String {
return "https://api.weibo.com/oauth2/authorize?client_id=/(client_id)&redirect_uri=/(redirect_uri)&display=mobile&forcelogin=true"
}


加载授权网页

webView.loadRequest(request)


截取code
WebView代理

遵守协议并实现 shouldStartLoad 方法



extension WBOAuthViewController: UIWebViewDelegate{
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
}
}


截取code字段

code是跟随返回地址的参数



实现 shouldStartLoad 方法后可以得到所有网络请求 , 若请求包含字段 error_uri , 则授权失败 , 若请求字段包含 code , 则授权成功 , 得到正确的 code


是否包含字段



let urlString = request.url?.query, urlString.hasPrefix("error_uri or code")


截取code字段



let code = urlString.substring(from: "code=".endIndex)


处理AccessToken
请求token

5个必选参数



获取code之后立即发起token的网络请求 , 请求成功后保存到模型中 , 由于网络工具类直接返回 SwiftyJSON 对象 , 则可以通过 ObjectMapper ( ObjectMapper ) 转为模型对象



返回数据为字典,调用 json.dictionaryObject 方法



/// 请求Token信息
///
/// - Parameters:
/// - code: code description
/// - callBack: callBack description
func requestAccessToken(code: String, callBack: @escaping (WBUserInfo?) -> ()){
let urlString = "https://api.weibo.com/oauth2/access_token"
let paramenters = [
"client_id": client_id,
"client_secret": client_secret,
"grant_type": "authorization_code",
"code": code,
"redirect_uri": redirect_uri
]
HTTPTool.shared.requestWithParameters(url: urlString, method: .post, parameters: paramenters, success: { (json) in
let userInfo = Mapper<WBUserInfo>().map(JSONObject: json.dictionaryObject)
callBack(userInfo)
}) {
}
}


token本地化

模型转字典



var userData = userInfo.toJSON()


存储



func saveUserDefault(dict:[String: Any]) {
userDict = dict
UserDefaults.standard.set(dict, forKey: userInfoKey)
}


读取



func loadUserDefault() -> [String: Any]? {
if let data = UserDefaults.standard.dictionary(forKey: userInfoKey){
return data
}
return nil
}


根据token存储状态判断登录



func isLogin() -> Bool {
if let userDict = loadUserDefault() {
let isToken = userDict["access_token"] != nil
return isToken
}
return false
}



最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台