基于Swift语言开发微信、QQ和微博的SSO授权登录代码分析

一,总体架构
1,引入第三方库

除了必须引入对应的登录SDK外,额外引入了SDWebImage,SVProgressHUD,看名字大家都明白吧,引入登录SDK请各自看官方的开发文档,需要加入什么系统库文件,需要配置Other Linker Flags 等,请参考各自官方文档即可;

2,配置连接桥文件

因为创建的工程是基于Swift语言,目前官方SDK和其它三方库都是用OC写的,所以为了在swift中调用oc代码,需要配置连接桥文件Bridging-Header.h,搜索objective-C bridging Header健,然后在值里面输入XXXLogin/Bridging-Header.h,注意是绝对路径,里面可以输入需要调用的头文件,如

#import "WXApi.h"  
#import "SVProgressHUD.h"  
#import "UIImageView+WebCache.h"

     3,配置工程

因为是SSO跳转方式,需要配置URL Schemes,以便程序返回识别宿主程序,配置方法很简单,参考各自文档即可,在info里面可以可视化添加,各自的key值采用官方demo所提供;

二,微信
1,注册
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {  
        // Override point for customization after application launch.  
          
        //向微信注册  
        WXApi.registerApp(kWXAPP_ID)  
          
        return true  
    } 

2,授权登录
  1. override func viewDidLoad() {  
            super.viewDidLoad()  
            // Do any additional setup after loading the view, typically from a nib.  
              
            NSNotificationCenter.defaultCenter().addObserver(self, selector:"onRecviceWX_CODE_Notification:", name: "WX_CODE", object: nil)  
              
              
            let sendBtn:UIButton = UIButton()  
            sendBtn.frame = CGRectMake(30, 100, kIPHONE_WIDTH-60, 40)  
            sendBtn.backgroundColor = UIColor.redColor()  
            sendBtn.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)  
            sendBtn.setTitle("Swift版本之微信授权登录", forState: UIControlState.Normal)  
            sendBtn.addTarget(self, action: "sendBtnClick:", forControlEvents: UIControlEvents.TouchUpInside)  
            self.view.addSubview(sendBtn)  
              
              
            headerImg = UIImageView(frame: CGRectMake(30, 160, 120, 120))  
            headerImg.backgroundColor = UIColor.yellowColor()  
            self.view.addSubview(headerImg)  
              
            nicknameLbl.frame = CGRectMake(170, 160, kIPHONE_WIDTH-60-140, 40)  
            nicknameLbl.backgroundColor = UIColor.lightGrayColor()  
            nicknameLbl.textColor = UIColor.purpleColor()  
            nicknameLbl.textAlignment = NSTextAlignment.Center  
            self.view.addSubview(nicknameLbl)  
              
        }  
          
          
        func sendBtnClick(sneder:UIButton)  
        {  
            sendWXAuthRequest()  
        }  
          
        //微信登录 第一步  
        func sendWXAuthRequest(){  
              
            let req : SendAuthReq = SendAuthReq()  
            req.scope = "snsapi_userinfo,snsapi_base"  
            WXApi .sendReq(req)  
        }

3,回调
  1. func onResp(resp: BaseResp!) {  
             
           /* 
            
           ErrCode  ERR_OK = 0(用户同意) 
           ERR_AUTH_DENIED = -4(用户拒绝授权) 
           ERR_USER_CANCEL = -2(用户取消) 
           code 用户换取access_token的code,仅在ErrCode为0时有效 
           state    第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K 
           lang 微信客户端当前语言 
           country  微信用户当前国家信息 
           */  
           // var aresp resp :SendAuthResp!  
           var aresp = resp as! SendAuthResp  
           //  var aresp1 = resp as? SendAuthResp  
             
           if (aresp.errCode == 0)  
           {  
               println(aresp.code)  
               //031076fd11ebfa5d32adf46b37c75aax  
                 
               var dic:Dictionary<String,String>=["code":aresp.code];  
               let value = dic["code"]  
               println("code:\(value)")  
                 
               NSNotificationCenter.defaultCenter().postNotificationName("WX_CODE", object: nil, userInfo: dic)  
                 
           }  
       }  
4,获取用户信息

//微信回调通知,获取code 第二步  
      
    func onRecviceWX_CODE_Notification(notification:NSNotification)  
    {  
        SVProgressHUD.showSuccessWithStatus("获取到code", duration: 1)  
          
        var userinfoDic : Dictionary = notification.userInfo!  
        let code: String = userinfoDic["code"] as! String  
          
        println("Recevice Code: \(code)")  
          
        self.getAccess_token(code)  
    }  
      
    //获取token 第三步  
    func getAccess_token(code :String){  
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code  
          
        var requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=\(kWXAPP_ID)&secret=\(kWXAPP_SECRET)&code=\(code)&grant_type=authorization_code"  
          
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {  
              
            var requestURL: NSURL = NSURL(string: requestUrl)!  
            var data = NSData(contentsOfURL: requestURL, options: NSDataReadingOptions(), error: nil)  
              
            dispatch_async(dispatch_get_main_queue(), {  
                  
                var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary  
                  
                println("Recevice Token: \(jsonResult)")  
                  
               
                SVProgressHUD.showSuccessWithStatus("获取到Token和openid", duration: 1)  
                  
                let token: String = jsonResult["access_token"] as! String  
                let openid: String = jsonResult["openid"] as! String  
                  
                  
                self.getUserInfo(token, openid: openid)  
                  
            })  
        })  
    }  
      
    //获取用户信息 第四步  
    func getUserInfo(token :String,openid:String){  
          
        // https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID  
        var requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=\(token)&openid=\(openid)"  
          
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {  
  
            var requestURL: NSURL = NSURL(string: requestUrl)!  
            var data = NSData(contentsOfURL: requestURL, options: NSDataReadingOptions(), error: nil)  
              
            dispatch_async(dispatch_get_main_queue(), {  
                  
                var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary  
                  
                println("Recevice UserInfo: \(jsonResult)")  
                  
                /* 
                Recevice UserInfo: 
                { 
                city = Chaoyang; 
                country = CN; 
                headimgurl = "http://wx.qlogo.cn/mmopen/FrdAUicrPIibcpGzxuD0kjfssQogj3icL8QTJQYUCLpgzSnvY6rJFGORreicPUiaPCzojwNlsXq4ibbc8e3gGFricWqJU5ia7ibicLVhfT/0"; 
                language = "zh_CN"; 
                nickname = "\U706b\U9505\U6599"; 
                openid = "oyAaTjkR8T6kcKWyA4VPYDa_Wy_w"; 
                privilege =     ( 
                ); 
                province = Beijing; 
                sex = 1; 
                unionid = "o1A_Bjg52MglJiEjhLmB8SyYfZIY"; 
                } 
                */  
                  
                SVProgressHUD.showSuccessWithStatus("获取到用户信息", duration: 1)  
                  
                let headimgurl: String = jsonResult["headimgurl"] as! String  
                let nickname: String = jsonResult["nickname"] as! String  
                  
                self.headerImg.sd_setImageWithURL(NSURL(string: headimgurl))  
                self.nicknameLbl.text = nickname  
            })  
        })  
    }

5,跳转
//微信的跳转回调  
   func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool    {  
       return  WXApi.handleOpenURL(url, delegate: self)  
   }  
 func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool
{  
        return  WXApi.handleOpenURL(url, delegate: self)  
} 

三,QQ
1,注册
  1. func sendBtnClick(sneder:UIButton)  
    {  
        sendQQAuthRequest()  
    }  
      
    //第一步  QQ登录  
    func sendQQAuthRequest(){  
          
        tencentOAuth = TencentOAuth(appId: kQQAPP_ID, andDelegate: self)  
        var permissions = [kOPEN_PERMISSION_GET_INFO,kOPEN_PERMISSION_GET_USER_INFO,kOPEN_PERMISSION_GET_SIMPLE_USER_INFO]  
        tencentOAuth.authorize(permissions, inSafari: false)  
          
    }  
2,授权登录

如上

3,回调
  1. //第二步 登录成功回调  
       func tencentDidLogin() {  
           let accessToken = tencentOAuth.accessToken  
      
           println("accessToken:\(accessToken)") //641B23508B62392C52D6DFADF67FAA9C  
      
           getUserInfo()  
       }  
         
       //失败  
       func tencentDidNotLogin(cancelled: Bool) {  
           println("登录失败了")  
       }  
         
       //无网络  
       func tencentDidNotNetWork() {  
           println("没有网络")  
       }  
4,获取用户信息
  1. //第三步 获取用户信息  
       func getUserInfo()  
       {  
           SVProgressHUD.showWithStatus("正在获取用户信息...")  
      
           tencentOAuth.getUserInfo()  
       }  
         
         
       //第四步 在获取用户回调中获取用户信息  
       func getUserInfoResponse(response: APIResponse!) {  
             
           SVProgressHUD.dismissWithSuccess("获取用户信息成功", afterDelay: 1)  
      
           var dic:Dictionary = response.jsonResponse  
             
           println("dic:\(dic)")  
             
           //        [is_lost: 0, figureurl: http://qzapp.qlogo.cn/qzapp/222222/C5527A2F775D9EA7C20317128FAC202B/30, vip: 0, is_yellow_year_vip: 0, province: 北京, ret: 0, is_yellow_vip: 0, figureurl_qq_1: http://q.qlogo.cn/qqapp/222222/C5527A2F775D9EA7C20317128FAC202B/40, yellow_vip_level: 0, level: 0, figureurl_1: http://qzapp.qlogo.cn/qzapp/222222/C5527A2F775D9EA7C20317128FAC202B/50, city: 海淀, figureurl_2: http://qzapp.qlogo.cn/qzapp/222222/C5527A2F775D9EA7C20317128FAC202B/100, nickname: 竹中雨滴, msg: , gender: 男, figureurl_qq_2: http://q.qlogo.cn/qqapp/222222/C5527A2F775D9EA7C20317128FAC202B/100]  
             
             
           refeshUserInfo(dic)  
       }  
         
         
       //第五步 刷新用户界面  
       func refeshUserInfo(dic : NSDictionary){  
         
           let headimgurl: String = dic["figureurl_qq_2"] as! String  
           let nickname: String = dic["nickname"] as! String  
             
           self.headerImg.sd_setImageWithURL(NSURL(string: headimgurl))  
           self.nicknameLbl.text = nickname  
      
       } 
5,跳转
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {  
      return TencentOAuth.HandleOpenURL(url)  
  }  
    
  func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool {  
      return TencentOAuth.HandleOpenURL(url)  
  }


四,微博
1,注册
  1. func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {  
           // Override point for customization after application launch.  
             
           WeiboSDK.registerApp(kAppKey)  
             
           return true  
       }
2,授权登录
  1. func sendBtnClick(sneder:UIButton)  
        {  
            sendSinaAuthRequest()  
        }  
          
        //第一步  微博登录  
        func sendSinaAuthRequest(){  
              
            var request : WBAuthorizeRequest = WBAuthorizeRequest.request() as! WBAuthorizeRequest  
            request.redirectURI = kRedirectURI  
            request.scope = "all"  
            request.userInfo = ["SSO_Key":"SSO_Value"]  
            WeiboSDK.sendRequest(request)  
        } 
3,回调
  1. func didReceiveWeiboRequest(request: WBBaseRequest!) {  
      
        }  
          
        func didReceiveWeiboResponse(response: WBBaseResponse!) {  
        
            if response.isKindOfClass(WBAuthorizeResponse){  
      
                if (response.statusCode == WeiboSDKResponseStatusCode.Success) {  
                  
                    var authorizeResponse : WBAuthorizeResponse = response as! WBAuthorizeResponse  
                    var userID = authorizeResponse.userID  
                    var accessToken = authorizeResponse.accessToken  
                      
                    println("userID:\(userID)\naccessToken:\(accessToken)")  
                      
                    var userInfo = response.userInfo as Dictionary  
                      
                    NSNotificationCenter.defaultCenter().postNotificationName("SINA_CODE", object: nil, userInfo: userInfo)  
      
                }  
            }  
        }

4,获取用户信息

  1. //第二步  通过通知得到登录后获取的用户信息  
        func onRecviceSINA_CODE_Notification(notification:NSNotification)  
        {  
            SVProgressHUD.showSuccessWithStatus("获取到用户信息", duration: 1)  
              
            var userinfoDic : Dictionary = notification.userInfo!  
              
            println("userInfo:\(userinfoDic)")  
              
              
            /* 
            userID:2627289515 
            accessToken:2.002BqnrCyY87OC80500cab28Ofqd3B 
            userInfo: 
            [uid: 2627289515, remind_in: 647057, scope: invitation_write, refresh_token: 2.002BqnrCyY87OC10f7877765yPietB, 
            app: { 
            logo = "http://ww1.sinaimg.cn/square/65745bf7jw1ea399us692j2028028glf.jpg"; 
            name = "SDK\U5fae\U535a\U5e94\U7528demo"; 
            },  
            access_token: 2.002BqnrCyY87OC80500cab28Ofqd3B, expires_in: 647057 
            ] 
             
            */  
              
            var userAppInfo: Dictionary<String,String> = userinfoDic["app"] as! Dictionary  
              
            refeshUserInfo(userAppInfo)  
        }  
      
        //第三步 刷新用户界面  
        func refeshUserInfo(dic : NSDictionary){  
              
            let headimgurl: String = dic["logo"] as! String  
            let nickname: String = dic["name"] as! String  
              
            self.headerImg.sd_setImageWithURL(NSURL(string: headimgurl))  
            self.nicknameLbl.text = nickname  
        } 
5,跳转
  1. func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {  
            return WeiboSDK.handleOpenURL(url, delegate: self)  
        }  
          
        func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool {  
            return WeiboSDK.handleOpenURL(url, delegate: self)  
        }








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值