在码农港湾
做一个实实在在的内行人

基于第三方微信授权登录的iOS代码分析

基于第三方的微信授权登录是之前笔者博文《QQ和新浪微博授权登录》的姊妹篇,微信已经深入到每一个APP的缝隙,最常用的莫过分享和登录了,接下来就以代码的形式来展开微信登录的相关说明,至于原理级别的oauth2.0认证体系请参考微信开放平台的相关说明和图示 https://open.weixin.qq.com/

三,微信登录授权开发:

1,到微信开发平台注册相关APP,现在是等待审核成功后才能获取到对应的key和secret;获取成功后需要单独申请开通登录和支付接口,如图

2,和QQ类似,需要填写Url Schemes,如demo中的wxd930ea5d5a258f4f ,然后引入相应framework;

3,在AppDelegate中注册和实现授权后的回调函数,代码如下:

  1. //向微信注册
  2.   [WXApi registerApp:kWXAPP_ID withDescription:@”weixin”];
  1. //授权后回调 <span style=”font-family: Arial;”>WXApiDelegate</span>
  2. -(void)onResp:(BaseReq *)resp
  3. {
  4.    /*
  5.     ErrCode ERR_OK = 0(用户同意)
  6.     ERR_AUTH_DENIED = -4(用户拒绝授权)
  7.     ERR_USER_CANCEL = -2(用户取消)
  8.     code    用户换取access_token的code,仅在ErrCode为0时有效
  9.     state   第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
  10.     lang    微信客户端当前语言
  11.     country 微信用户当前国家信息
  12.     */
  13.     SendAuthResp *aresp = (SendAuthResp *)resp;
  14.     if (aresp.errCode== 0) {
  15.         NSString *code = aresp.code;
  16.         NSDictionary *dic = @{@”code”:code};
  17.     }
  18. }

 

  1. //和QQ,新浪并列回调句柄
  1. – (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
  2. {
  3.     return [TencentOAuth HandleOpenURL:url] ||
  4.     [WeiboSDK handleOpenURL:url delegate:self] ||
  5.     [WXApi handleOpenURL:url delegate:self];;
  6. }
  7. – (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
  8. {
  9.     return [TencentOAuth HandleOpenURL:url] ||
  10.     [WeiboSDK handleOpenURL:url delegate:self] ||
  11.     [WXApi handleOpenURL:url delegate:self];;
  12. }

4,微信登录授权比较复杂,相比QQ,新浪多了几步,简单说就是需要三步,第一步,获取code,这个用来获取token,第二步,就是带上code获取token,第三步,根据第二步获取的token和openid来获取用户的相关信息;

下面用代码来实现:

第一步:code

  1. – (IBAction)weixinLogin:(id)sender
  2. {
  3.     [self sendAuthRequest];
  4. }
  5. -(void)sendAuthRequest
  6. {
  7.     SendAuthReq* req =[[SendAuthReq alloc ] init];
  8.     req.scope = @”snsapi_userinfo,snsapi_base”;
  9.     req.state = @”0744″ ;
  10.     [WXApi sendReq:req];
  11. }

这里获取后会调用之前在AppDelegate里面的对应oauthResp回调,获得得到的code。

第二步:token和openid

  1. -(void)getAccess_token
  2. {
  3.     //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
  4.     NSString *url =[NSString stringWithFormat:@”https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code”,kWXAPP_ID,kWXAPP_SECRET,self.wxCode.text];
  5.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  6.         NSURL *zoneUrl = [NSURL URLWithString:url];
  7.         NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
  8.         NSData *data = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
  9.         dispatch_async(dispatch_get_main_queue(), ^{
  10.             if (data) {
  11.                 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  12.               /*
  13.                {
  14.                “access_token” = “OezXcEiiBSKSxW0eoylIeJDUKD6z6dmr42JANLPjNN7Kaf3e4GZ2OncrCfiKnGWiusJMZwzQU8kXcnT1hNs_ykAFDfDEuNp6waj-bDdepEzooL_k1vb7EQzhP8plTbD0AgR8zCRi1It3eNS7yRyd5A”;
  15.                “expires_in” = 7200;
  16.                openid = oyAaTjsDx7pl4Q42O3sDzDtA7gZs;
  17.                “refresh_token” = “OezXcEiiBSKSxW0eoylIeJDUKD6z6dmr42JANLPjNN7Kaf3e4GZ2OncrCfiKnGWi2ZzH_XfVVxZbmha9oSFnKAhFsS0iyARkXCa7zPu4MqVRdwyb8J16V8cWw7oNIff0l-5F-4-GJwD8MopmjHXKiA”;
  18.                scope = “snsapi_userinfo,snsapi_base”;
  19.                }
  20.                */
  21.                 self.access_token.text = [dic objectForKey:@”access_token”];
  22.                 self.openid.text = [dic objectForKey:@”openid”];
  23.             }
  24.         });
  25.     });
  26. }

 

利用GCD来获取对应的token和openID.

第三步:userinfo

  1. -(void)getUserInfo
  2. {
  3.    // https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
  4.     NSString *url =[NSString stringWithFormat:@”https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@”,self.access_token.text,self.openid.text];
  5.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  6.         NSURL *zoneUrl = [NSURL URLWithString:url];
  7.         NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
  8.         NSData *data = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
  9.         dispatch_async(dispatch_get_main_queue(), ^{
  10.             if (data) {
  11.                 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  12.                 /*
  13.                  {
  14.                  city = Haidian;
  15.                  country = CN;
  16.                  headimgurl = “http://wx.qlogo.cn/mmopen/FrdAUicrPIibcpGzxuD0kjfnvc2klwzQ62a1brlWq1sjNfWREia6W8Cf8kNCbErowsSUcGSIltXTqrhQgPEibYakpl5EokGMibMPU/0”;
  17.                  language = “zh_CN”;
  18.                  nickname = “xxx”;
  19.                  openid = oyAaTjsDx7pl4xxxxxxx;
  20.                  privilege =     (
  21.                  );
  22.                  province = Beijing;
  23.                  sex = 1;
  24.                  unionid = oyAaTjsxxxxxxQ42O3xxxxxxs;
  25.                  }
  26.                  */
  27.                 self.nickname.text = [dic objectForKey:@”nickname”];
  28.                 self.wxHeadImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dic objectForKey:@”headimgurl”]]]];
  29.             }
  30.         });
  31.     });
  32. }

执行到这一步就算完成了整个授权登录的功能,能把昵称和头像显示出来,剩下的就是及时刷新你的token,详情可参考开发文档。

下面是登录成功后的QQ,新浪微博,微信的真机运行成功截图:

评价:微信的开发文档相比容易理解和调试,虽然没有demo,但是文档比较详细,所以可以在一定程度上减轻了开发的困难,但是相比之下微信的授权步骤比较麻烦,需要三步才能彻底获取用户信息,这点没有QQ和新浪微博简洁,需要有一定的阅读和代码功底,希望能给大家带来帮助。

后记:微信授权登录是对QQ和新浪微博登录的姊妹篇,前两者登录代码分析请参考上一篇博文,如需三种登录方式的demo源代码,该demo只需换掉默认宏定义和Url Schemes中默认的key即可正式使用,详情请发Email:mmw05@163.com ,特别注意demo不免费提供,需要支付一定金额,谢谢合作!

附言:本博文属于原创博客,如需转载请注明出处,否则将追究法律责任,博客来源:http://blog.csdn.net/mapboo/article/details/39475015


好消息,新老用户赶快领取云产品优惠代金券吧

阿里云限量代金券腾讯云新客福利券

【阿里云】棒款特惠精选

云服务器低至8.1元/月 - 开始搭建你的博客吧

ad5