微信授权登录 java
首先 腾讯那么大的公司 文档写的那么low 微信那么火 demo写的那么差 我就想说一句
微信简直就是在歧视Java
网页版的微信登录
1.从前台默认发起静默授权
2.然后回调地址是后台处理方法 会自动带有参数进入后台 微信的那边回调会带有code和state 我给出我的案例 : http://ghs.daivd.com/auth?code=XZXXXXXX&state=123 这是个GET请求
3.回调到我们后台方法 然后截取code 然后通过code获取用户基础信息 我们主要需要就是 openid 和 用户access_token
4.获取我们公众号token(因为获取公众号token有限制 最好是存在缓存当汇总) 然后结合我们获取到的用户openid 来判断用户是否有关注我们公众号 如果没有我们就返回微信公众号关注页面 如果我们就可以进行获取用户信息 然后存在我们数据中
5.然后返回我们前台页面
一.授权
微信有两种网页授权
第一种是静默授权:不会给用户任何提示直接返回用户code 但是如果用户内有关注我们的公众号那么我们就没有办法拿到用户很全的信息
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
第二种是手动授权:会给用户弹出页面却要用户点击确认,用户点击后我们就能拿到用户的信息
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
下面是例子 注意是GET请求
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=XXXXX 这个是appid 可以在你微信公众平台中的 基础配置中找到
&
redirect_uri=这里填写的是回调地址 也就是微信登录后 返回访问的地址 一般会填写后台地址 因为回调是会带有code值然后后台可以通过code拿到用户access_token *重点是你的回调地址需要使用urlEncode进行连接处理 直接百度urlEncode 有网页版帮忙处理
&
response_type=code 这个是返回类型 不要改 返回类型,请填写code
&
scope=这里填写登录类别 也就是我们上面说的 静默授权或者是手动授权 snsapi_base(静默)/snsapi_userinfo(手动)
&
state=123 我们可以自定义参数 重定向后会带上state参数,可以填写a-zA-Z0-9的参数值,最多128字节
#wechat_redirect 这个是微信必填参数 不能改变
下面是给出的案例
静默 https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXX&redirect_uri=http%3a%2f%2fghs.david.com%2fauth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
手动 https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXX&redirect_uri=http%3a%2f%2fghs.david.com%2fauth&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
这两个就是从前台发起的授权请求
二.回调方法
通过我们填写的回调url他会进入我们后台回调方法
这里讲一下这些apiurl返回的json
一
//获取微信公众号的通用access_token每天只能取2000次 每次token有效期是7200S 所以在自己动手写最好放在缓存中 我的项目放在redis中
//grant_type=获取access_token填写client_credential(必填) appid=填写我们的appid(必填) secret=填写微信公众号的AppSecret(必填)
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", 填写微信APPID).replace("APPSECRET", 填写微信公众号的AppSecret);
返回的JSON
{
"access_token":"ACCESS_TOKEN",//获取到的凭证
"expires_in":7200 //凭证有效时间,单位:秒
}
二
//通过微信的appid 和 微信公众号的AppSecret 以及我们获取到的针对用户授权回调的code 拿到 这个用户的 openid和access_token appid=填写我们的appid(必填) secret=填写微信公众号的AppSecret(必填) grant_type=获取access_token填写authorization_code(必填)
String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code".replace("APPID", 填写微信APPID).replace("APPSECRET", 填写微信公众号的AppSecret).replace("CODE", code);
返回的JSON
{
"access_token":"ACCESS_TOKEN", //用户的access_token 官网解释:网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
"expires_in":7200, //access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN", //用户刷新access_token(不知道)
"openid":"OPENID", //用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID (这个是重点 我们主要就是为了这个)
"scope":"SCOPE" //用户授权的作用域,使用逗号(,)分隔(不知道)
}
三
//这里是获取用户在我们公众里面的信息 如果没有关注公众号那么就没有办法获取详细信息 参数需要 微信公众号通用token 和 用户openid 还有 lang =返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN".replace("ACCESS_TOKEN", wxgzhToken).replace("OPENID", openid);
返回的JSON
{
"subscribe": 1, //用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", //用户的标识,对当前公众号唯一
"nickname": "Band", //用户的昵称
"sex": 1, // 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
"language": "zh_CN", // 用户的语言,简体中文为zh_CN
"city": "广州", // 用户所在城市
"province": "广东", // 用户所在省份
"country": "中国", // 用户所在国家
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效
"subscribe_time": 1382694957,//用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL", // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段 (这个我也没有搞清楚)
"remark": "",//公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
"groupid": 0 // 用户所在的分组ID
}
希望我的分享可以帮助到大家避免一些坑
首先 腾讯那么大的公司 文档写的那么low 微信那么火 demo写的那么差 我就想说一句
微信简直就是在歧视Java
我这边自己整合了下 微信支付和微信登录 java的代码 我打包出来了
不是让你们直接使用的 是需要你们自己看看 借鉴的
http://download.csdn.net/download/qq_36020545/10129501
网页版的微信登录
获取APPID和AppSecret
1.从前台默认发起静默授权
2.然后回调地址是后台处理方法 会自动带有参数进入后台 微信的那边回调会带有code和state 我给出我的案例 : http://ghs.daivd.com/auth?code=XZXXXXXX&state=123 这是个GET请求
3.回调到我们后台方法 然后截取code 然后通过code获取用户基础信息 我们主要需要就是 openid 和 用户access_token
4.获取我们公众号token(因为获取公众号token有限制 最好是存在缓存当汇总) 然后结合我们获取到的用户openid 来判断用户是否有关注我们公众号 如果没有我们就返回微信公众号关注页面 如果我们就可以进行获取用户信息 然后存在我们数据中
5.然后返回我们前台页面
一.授权
微信有两种网页授权
第一种是静默授权:不会给用户任何提示直接返回用户code 但是如果用户内有关注我们的公众号那么我们就没有办法拿到用户很全的信息
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
第二种是手动授权:会给用户弹出页面却要用户点击确认,用户点击后我们就能拿到用户的信息
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
下面是例子 注意是GET请求
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=XXXXX 这个是appid 可以在你微信公众平台中的 基础配置中找到
&
redirect_uri=这里填写的是回调地址 也就是微信登录后 返回访问的地址 一般会填写后台地址 因为回调是会带有code值然后后台可以通过code拿到用户access_token *重点是你的回调地址需要使用urlEncode进行连接处理 直接百度urlEncode 有网页版帮忙处理
&
response_type=code 这个是返回类型 不要改 返回类型,请填写code
&
scope=这里填写登录类别 也就是我们上面说的 静默授权或者是手动授权 snsapi_base(静默)/snsapi_userinfo(手动)
&
state=123 我们可以自定义参数 重定向后会带上state参数,可以填写a-zA-Z0-9的参数值,最多128字节
#wechat_redirect 这个是微信必填参数 不能改变
下面是给出的案例
静默 https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXX&redirect_uri=http%3a%2f%2fghs.david.com%2fauth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
手动 https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXX&redirect_uri=http%3a%2f%2fghs.david.com%2fauth&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
这两个就是从前台发起的授权请求
二.回调方法
通过我们填写的回调url他会进入我们后台回调方法
- public void weixinLogin(HttpServletRequest request,HttpServletResponse response) throws Exception {
- Map<String, String[]> params = request.getParameterMap();//针对get获取get参数
- String[] codes = params.get("code");//拿到的code的值
- String code = codes[0];//code
- //这一步就是拼写微信api请求地址并 通过微信的appid 和 微信公众号的AppSecret 以及我们获取到的针对用户授权回调的code 拿到 这个用户的 openid和access_token
- String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code".replace("APPID", 填写微信APPID).replace("APPSECRET", 填写微信公众号的AppSecret).replace("CODE", code);
- String requestResult = HttpTookit.doGet(requestUrl);//我们需要自己写或者在网上找一个 doGet 方法 发送doGet请求
- JSONObject getCodeResultJson = JSON.parseObject(requestResult);//把请求成功后的结果转换成JSON对象
- if(getCodeResultJson == null || getCodeResultJson.getInteger("errcode") != null || getCodeResultJson.getString("openid") == null) {
- throw 这里需要抛异常 如果返回值没有 或者 出现错误返回errcode 或者 没有拿到openid
- }
- String openid = getCodeResultJson.getString("openid");//拿到openid
- //我们需要获取当前公众号通用的access_token 和用户的access_token是不一样的
- //这里我为了让大家可以方便就没有写太复杂 因为微信他那边获取微信公众号的通用access_token每天只能取2000次 每次token有效期是7200S 所以在自己动手写最好放在缓存中 我的项目放在redis中
- String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", 填写微信APPID).replace("APPSECRET", 填写微信公众号的AppSecret);
- String requestResult = HttpTookit.doGet(requestUrl);
- JSONObject weixinToken = JSON.parseObject(requestResult);
- if(jsonObject == null){
- throw 这里需要抛异常 获取我们公众号token失败
- }
- String wxgzhToken = accessToken.setToken(jsonObject.getString("access_token"));
- //这里是获取用户在我们公众里面的信息 如果没有关注公众号那么就没有办法获取详细信息 参数需要 微信公众号通用token 和 用户openid
- String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN".replace("ACCESS_TOKEN", wxgzhToken).replace("OPENID", openid);
- String requestResult = HttpTookit.doGet(requestUrl);
- JSONObject user = JSON.parseObject(requestResult);
- if(user == null || user.getInteger("errcode") != null ) {
- 抛异常
- }
- Integer subscribe = user.getInteger("subscribe");//是否有关注我们公众号
- if(subscribe == 0){//没有关注我们公众号
- response.sendRedirect("https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIyNTc1MDQ2Mw==&scene=110#wechat_redirect");//跳到我们公众号关注页面 url地址需要你么你自己去截取
- }else{//关注了
- 如果关注了
- user中就会有详细的信息 我们既可以把这些信息存在我们的数据库中
- 然后跳转到我们前台页面
- }
- }
这里讲一下这些apiurl返回的json
一
//获取微信公众号的通用access_token每天只能取2000次 每次token有效期是7200S 所以在自己动手写最好放在缓存中 我的项目放在redis中
//grant_type=获取access_token填写client_credential(必填) appid=填写我们的appid(必填) secret=填写微信公众号的AppSecret(必填)
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", 填写微信APPID).replace("APPSECRET", 填写微信公众号的AppSecret);
返回的JSON
{
"access_token":"ACCESS_TOKEN",//获取到的凭证
"expires_in":7200 //凭证有效时间,单位:秒
}
二
//通过微信的appid 和 微信公众号的AppSecret 以及我们获取到的针对用户授权回调的code 拿到 这个用户的 openid和access_token appid=填写我们的appid(必填) secret=填写微信公众号的AppSecret(必填) grant_type=获取access_token填写authorization_code(必填)
String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code".replace("APPID", 填写微信APPID).replace("APPSECRET", 填写微信公众号的AppSecret).replace("CODE", code);
返回的JSON
{
"access_token":"ACCESS_TOKEN", //用户的access_token 官网解释:网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
"expires_in":7200, //access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN", //用户刷新access_token(不知道)
"openid":"OPENID", //用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID (这个是重点 我们主要就是为了这个)
"scope":"SCOPE" //用户授权的作用域,使用逗号(,)分隔(不知道)
}
三
//这里是获取用户在我们公众里面的信息 如果没有关注公众号那么就没有办法获取详细信息 参数需要 微信公众号通用token 和 用户openid 还有 lang =返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN".replace("ACCESS_TOKEN", wxgzhToken).replace("OPENID", openid);
返回的JSON
{
"subscribe": 1, //用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", //用户的标识,对当前公众号唯一
"nickname": "Band", //用户的昵称
"sex": 1, // 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
"language": "zh_CN", // 用户的语言,简体中文为zh_CN
"city": "广州", // 用户所在城市
"province": "广东", // 用户所在省份
"country": "中国", // 用户所在国家
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效
"subscribe_time": 1382694957,//用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL", // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段 (这个我也没有搞清楚)
"remark": "",//公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
"groupid": 0 // 用户所在的分组ID
}
希望我的分享可以帮助到大家避免一些坑