java后端 三方登录之微信登录 开发详细流程以及遇到过的坑 总结(非常详细) 2017-12-26

上一篇写了qq登录,其实微信登录和qq登录几乎一个逻辑,一个写完,另一个就简单了

一、第三方登录接口申请流程,并且拿到code

这里的获取key和id也是有2个地方,一个是微信公众平台,一个是微信开放平台,pc和app的https://open.weixin.qq.com/去这个地址申请创建,而h5则在微信公众平台申请

申请成功之后,根据官网的流程:先来看微信的pc登录吧:

首先根据你的申请的信息,配置到这个url上:

https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

这个时候,前端会生成一个二维码,给用户扫描,扫描登录后,会跟之前一样返回一个code,传给我,如果是在微信里点击链接唤醒微信(后面为了方便都叫做h5)登录,则调这个地址:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=redirect_uri&response_type=code&scope=snsapi_userinfo&state=&connect_redirect=1#wechat_redirect

 

这样就不会生成二维码,而是唤起微信,进行授权登录(用户退出后,再次登陆,需要用户重新授权)

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_inaccess_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;
}

 

 

 

 

 

 


版权声明:本文为qq_33223761原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。