第三方微信登录 | 静默授权与网页授权的实现

11,148 阅读6分钟

一:介绍

第三方登录有QQ、微信、微博、支付宝等等,如果现在自己的项目中实现这些登录,即可以使用友盟的sdk,也可以一个一个接入,各有各的有点,这里不做赘述。

今天和大家分享的是,在项目中实现微信登录,虽然微信官网给出了接入文档,但是我在接入的过程中,遇到一些问题,在此做出总结以便大家参考。主要讲微信snsapi_base静默授权与snsapi_userinfo网页授权的实现。

关注 【网罗开发】微信公众号,网罗天下方法,方便你我开发,更多iOS技术干货等待领取,所有文档会持续更新,欢迎关注一起成长!

二:准备工作

移动应用微信登录是基于OAuth2.0标准协议构建的微信OAuth2.0授权登录系统。

在进行微信OAuth2.0授权登录接入之前,需要完成一下工作才可以开始介接入:

  1. 在微信开放平台注册开发者帐号;
  2. 拥有一个已审核通过的移动应用;
  3. 并获得相应的AppID和AppSecret;
  4. 申请微信登录且通过审核。

三:授权流程

微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:

  1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
  2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
  3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

获取access_token时序图:

h.png

四:静默授权与网页授权的实现

1. 静默授权与网页授权的区别

网页授权:

req.scope = @"snsapi_userinfo";

静默授权:

req.scope = @"snsapi_base";

snsapi_base与snsapi_userinfo属于微信网页授权获取用户信息的两种作用域:

snsapi_base只能获取access_token和openID

snsapi_userinfo可以获取更详细的用户资料,比如头像、昵称、性别等

2. 获取CODE

再登录按钮的点击事件中写入一下代码:

    //构造SendAuthReq结构体
    SendAuthReq* req =[[[SendAuthReq alloc]init]autorelease];
    req.scope = @"snsapi_userinfo";
    req.state = @"123";
    //第三方向微信终端发送一个SendAuthReq消息结构
    [WXApi sendReq:req];

在AppDelegate的didFinishLaunchingWithOptions方法中注册:

[WXApi registerApp:@"wx1234567890"];

"wx1234567890"为appid,请更换为自己项目的appid

拉起微信打开授权登录页如下图:

点击确认登陆,授权后回调 WXApiDelegate

-(void)onResp:(BaseReq *)resp
{
    /*
     ErrCode ERR_OK = 0(用户同意)
     ERR_AUTH_DENIED = -4(用户拒绝授权)
     ERR_USER_CANCEL = -2(用户取消)
     code    用户换取access_token的code,仅在ErrCode为0时有效
     state   第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
     lang    微信客户端当前语言
     country 微信用户当前国家信息
     */
    
    if ([resp isKindOfClass:[SendAuthResp class]]) //判断是否为授权请求,否则与微信支付等功能发生冲突
    {
        SendAuthResp *aresp = (SendAuthResp *)resp;
        if (aresp.errCode== 0)
        {
            NSLog(@"code %@",aresp.code);
            [[NSNotificationCenter defaultCenter] postNotificationName:@"wechatDidLoginNotification" object:self userInfo:@{@"code":aresp.code}];
        }
    }
}

使用通知,将aresp.code传递到登录页面

3. 通过code获取access_token

在登录页面通过通知,获取到code之后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

参数说明:

  • appid:应用唯一标识,在微信开放平台提交应用审核通过后获得
  • secret:应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
  • code:填写第一步获取的code参数
  • grant_type:填authorization_code

网络请求返回的参数格式如下:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

参数说明:

  • access_token:接口调用凭证
  • expires_in:access_token接口调用凭证超时时间,单位(秒)
  • refresh_token:用户刷新access_token
  • openid:授权用户唯一标识
  • scope:用户授权的作用域,使用逗号(,)分隔
  • unionid:当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段

4. 注意:

  1. 建议将Appsecret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求:
  • Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);

  • access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;

  • refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

  1. 要注意网络授权网页授权access_token 与 普通access_token的区别:
  • 网页授权的access_token在每次获取openID时一起更新,在接口调用频次限制中为“无上限”;
  • 普通access_token一般限制为2000次/日,需要自己保存起来并定时更新。

到这里同时获得access_token和openid,静默授权与网页授权操作都是一样的。根据官网文档,网页授权还可以进一步操作,获取用户更多详细信息。

5. 获取用户个人信息(UnionID机制)

此接口用于获取用户个人信息,开发者可通过OpenID来获取用户基本信息,接口如下:

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

参数说明:

  • access_token:调用凭证
  • openid:普通用户的标识,对当前开发者帐号唯一

正确的Json返回结果:

{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

6. 静默授权获取到用户详细资料

在第3步通过snsapi_base,同时获得access_token和openid,

把这里的access_token和openid用于下面接口中:

https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 

参数说明:

  • access_token:调用凭证
  • openid:普通用户的标识,对当前开发者帐号唯一
  • lang:国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN

Json返回结果和snsapi_userinfo下获取的用户详情一样。

但是这个方法的前提是同一个公众号内,用户关注了,如果是其他公众号,还是需要用户点击授权的。

希望可以帮助大家,如有问题可加QQ技术交流群: 668562416 如果哪里有什么不对或者不足的地方,还望读者多多提意见或建议

如需转载请联系我,经过授权方可转载,谢谢

本篇已同步到个人博客:FBY展菲


欢迎关注我的公众号:网罗开发