微信的第三方登录详解
根据公司需要,特将APP微信第三方登录予以详解,以共享我这几天的研究成果。
第一步:准备工作
微信登录不同于其他第三方登录,相对来说比较麻烦一点,网上的列子也相对少一点,在微信开放平台注册完应用通过审核之后,得到AppId和AppSecret。就可以进行微信分享等功能,但是要想实现微信登录就必须进行认证。这个认证需要300元。
注册应用的时候签名要用微信官方提供的APK所生成密钥,因为这是一一对应的,如果报名和签名不一致的话,在程序进行微信注册的时候是不会成功的。
当我们应用审核通过并且获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。流程如图所示:
微信登录很关键的一步就是获取code
在你的点击事件里面写下下面一段代码:
Android平台应用授权登录接入代码示例(请参考Android接入指南):
{
// send oauthrequest
Final SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_demo_test";
api.sendReq(req);
}
微信将会自动的去跳转请求授权页面,
用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。这一句是很难让人理解的。我就是在这一句上面迷糊了好几天。
这个时候呢,我们就应该看微信的这一个页面了
[3] 接收微信的请求及返回值
如果你的程序需要接收微信发送的请求,或者接收发送到微信请求的响应结果,需要下面3步操作:
a. 在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(例如应用程序的包名为net.sourceforge.simcpux,则新添加的类如下图所示)
并在manifest文件里面加上exported属性,设置为true,例如:
之所以必须在这里重新建包,并规定好类名,应该是在微信官方端已经写死了要传出的activity,所以要求开发者必须写死。
这一句就充分证明了这一点嘛!
b. 实现IWXAPIEventHandler接口,微信发送的请求将回调到onReq方法,发送到微信请求的响应结果将回调到onResp方法
c. 在WXEntryActivity中将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWXAPI接口的handleIntent方法,示例如下图:
当微信发送请求到你的应用,将通过IWXAPIEventHandler接口的onReq方法进行回调,类似的,应用请求微信的响应结果将通过onResp回调。
下面说说回调函数,我在做这个的时候用的是eclipse,不知道你们会用什么开发工具。但是不得不吐槽,我在debug的时候断点根本就debug不到onResp里面。甚至都没有debug WXEntryActivity里面,当时有授权界面,但是点击确定之后,就直接返回了,或者就什么也没有了(后来知道是诶有设置界面,呵呵)。说说最想知道的一步吧,获得code等信息。微信的返回信息直接返回WXEntryActivity类里面,上面<C>当中的onResp中这样写:
SendAuth.Respre = (SendAuth.Resp) resp;
int expireDate = re.expireDate;//过期时间
Log.i("onResp","expireDate" + expireDate);
int errCode = re.errCode;//错误码
Log.i("onResp","errCode" + errCode);
String errStr = re.errStr;//错误描述
Log.i("onResp","errStr" + errStr);
String state = re.state; //状态
Log.i("onResp","state" + state);
String token = re.token;//应该是类似code
Log.i("onResp","token" + token);
String resultUrl = re.resultUrl;//应该是url
Log.i("onResp","resultUrl" + resultUrl);
这样就能够获得你所需要的code了,至于下面几步怎么做相信各位同仁都知道怎么做了,因为源码涉及公司一些保密信息,就不在此公布了,有疑问可以发我邮箱。谢谢,不过下面几步还是给大家贴出来。
注意
如果需要混淆代码,为了保证sdk的正常使用,需要在proguard.cfg加上下面两行配置:
-keep classcom.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implementscom.tencent.mm.sdk.openapi.WXMediaMessag
用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。
返回值 | 说明 |
ErrCode | ERR_OK = 0(用户同意) |
code | 用户换取access_token的code,仅在ErrCode为0时有效 |
state | 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K |
lang | 微信客户端当前语言 |
country | 微信用户当前国家信息 |
第二步:通过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"
}
参数 | 说明 |
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
错误返回样例:
{"errcode":40029,"errmsg":"invalidcode"}
刷新access_token有效期
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
1. 1.若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 2.若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
请求方法
获取第一步的code后,请求以下链接进行refresh_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
参数说明
参数 | 是否必须 | 说明 |
appid | 是 | 应用唯一标识 |
grant_type | 是 | 填refresh_token |
refresh_token | 是 | 填写通过access_token获取到的refresh_token参数 |
返回说明
正确的返回:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数 | 说明 |
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
错误返回样例:
{"errcode":40030,"errmsg":"invalidrefresh_token"}
第三步:通过access_token调用接口
获取access_token后,进行接口调用,有以下前提:
1. 1. access_token有效且未超时;
2. 2.微信用户已授权给第三方应用帐号相应接口作用域(scope)。
对于接口作用域(scope),能调用的接口有以下:
授权作用域(scope) | 接口 | 接口说明 |
snsapi_base | /sns/oauth2/access_token | 通过code换取access_token、refresh_token和已授权scope |
/sns/oauth2/refresh_token | 刷新或续期access_token使用 | |
/sns/auth | 检查access_token有效性 | |
snsapi_userinfo | /sns/userinfo | 获取用户个人信息 |
其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。
如有疑问请发邮件到:heweichao8@126.com