上一篇写了qq登录,其实微信登录和qq登录几乎一个逻辑,一个写完,另一个就简单了
一、第三方登录接口申请流程,并且拿到code
这里的获取key和id也是有2个地方,一个是微信公众平台,一个是微信开放平台,pc和app的https://open.weixin.qq.com/去这个地址申请创建,而h5则在微信公众平台申请
申请成功之后,根据官网的流程:先来看微信的pc登录吧:
首先根据你的申请的信息,配置到这个url上:
这个时候,前端会生成一个二维码,给用户扫描,扫描登录后,会跟之前一样返回一个code,传给我,如果是在微信里点击链接唤醒微信(后面为了方便都叫做h5)登录,则调这个地址:
这样就不会生成二维码,而是唤起微信,进行授权登录(用户退出后,再次登陆,需要用户重新授权)
app端的话,也是由前端给我,这个的ios和android都是一样的,都是在开放平台申请的应用里 这里需要注意一点,就是如果有买家,卖家,那需要注册2个app的id和key,然后在不同环境下,比如预发,测试,正式,pc需要申请不同的appid和key,因为每个微信项目只能对应一个回调地址,而app的话不同环境只要一个就可以了,因为app没有回调地址
这里注意的是,和qq不同,微信可以只配置顶级域名,即配置了www.jiddn.com,那么回调www.jiddn.com/index也是可以的
二、成功授权后回调
1.根据code获取token:
第一步:通过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授权时,才会出现该字段。 |
错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}
2.获取用户个人信息(UnionID机制)
接口说明
此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。请注意,在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况。
请求说明
http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
| 参数 | 是否必须 | 说明 |
|---|---|---|
| access_token | 是 | 调用凭证 |
| openid | 是 | 普通用户的标识,对当前开发者帐号唯一 |
| lang | 否 | 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN |
返回说明
正确的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"}
| 参数 | 说明 |
|---|---|
| openid | 普通用户的标识,对当前开发者帐号唯一 |
| nickname | 普通用户昵称 |
| sex | 普通用户性别,1为男性,2为女性 |
| province | 普通用户个人资料填写的省份 |
| city | 普通用户个人资料填写的城市 |
| country | 国家,如中国为CN |
| headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 |
| privilege | 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) |
| unionid | 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 |
建议:
开发者最好保存用户unionID信息,以便以后在不同应用中进行用户信息互通。
错误的Json返回示例:
{ "errcode":40003,"errmsg":"invalid openid"}
微信是直接获取到unionid的,不像qq,还需要申请,然后其他逻辑和qq一样,存表,查等等,app的code前端生成传给我,拿到code之后的逻辑也是一样的。
总结一下微信登录所遇到的坑:app登录的时候,会发现没有unionid这个字段,原因是没有把公众号绑定到开放平台上,绑定一下就会有unionid这个字段了
还有微信获取昵称的时候,会出现中文乱码的时候,这个时候,这样去拿获取到的信息:
public Map<String, Object> getUserInfo(String accessToken,String openId,String refreshAccessToken) {
String url = getUserInfoUrl + "access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN";
String jsonUserStr = null;
try {
URL url1 = new URL(url);
HttpURLConnection urlConnection = null;
urlConnection = (HttpURLConnection)url1.openConnection();
// 将返回的输入流转换成字符串
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
BufferedReader in = new BufferedReader(inputStreamReader);
jsonUserStr =in.readLine().toString();
System.out.println("jsonUserStr = "+jsonUserStr);
// 释放资源
inputStream.close();
inputStream = null;
urlConnection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
if(jsonUserStr==null){
throw new JSONException("[WX] GET USERINFO FAILED");
}
Map<String, Object> mapResp = jsonMapper.fromJson(jsonUserStr, Map.class);
return mapResp;
}就行了,和qq相同,所有的接口都是get形式去调用的,微信返回的全部是json格式的,比qq正规多了。其实还有可能存在token过期的问题,但是测试中一直没有出现这个问题,或者过期了,重新登录授权就可以了,所以也没去解决这个,目前看来没有带来问题。
另外,qq审核比较快,微信审核比较慢,并且微信同时审核不同回调地址的时候,注意名称不要一样,否则只会审核通过一个。
后台需要配置的微信相关的信息要6个,是pc app h5的appid和appkey,ios和android都是同一个appid和appkey
最后,添上我get请求的代码,qq和微信是同一个方法:
/**
* 发送qqGET请求
* @param url 请求url
* @return map结果集
*/
public String get(String url){
String jsonResp = doGet(url);
log.info("[qq]: do get request({}), and get response({}).", url, jsonResp);
return jsonResp;
}
private String doGet(String url){
String jsonResp = HttpRequest.get(url).body();
return jsonResp;
}