一、用户同意授权,获取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=****&redirect_uri=uriLink&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
其中uriLink为urlEncode后的获取code之后的跳转链接
appid为自己公众号的appid
scope为snsapi_userinfo,以便直接获取用户信息
URL编码代码如下:
/**
* URL编码(utf-8)
*
* @param source
* @return
*/
public static String urlEncodeUTF8(String source) {
String result = source;
try {
result = java.net.URLEncoder.encode(source, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
二、通过code换取网页授权access_token
/**
* 获取网页授权凭证
*
* appId 公众账号的唯一标识
* appSecret 公众账号的密钥
* code
* @return WeixinAouth2Token
* @throws JSONException
*/
public static Oauth2Token getOauth2AccessToken(String appId, String appSecret, String code) throws JSONException {
Oauth2Token wat = null;
// 拼接请求地址
String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
requestUrl = requestUrl.replace("APPID", appId);
requestUrl = requestUrl.replace("SECRET", appSecret);
requestUrl = requestUrl.replace("CODE", code);
// 获取网页授权凭证
JSONObject jsonObject = new JSONObject(NetUtil.get(requestUrl));
if (null != jsonObject) {
try {
wat = new Oauth2Token();
wat.setAccessToken(jsonObject.getString("access_token"));
wat.setExpiresIn( (Integer) jsonObject.get("expires_in"));
wat.setRefreshToken(jsonObject.getString("refresh_token"));
wat.setOpenId(jsonObject.getString("openid"));
wat.setScope(jsonObject.getString("scope"));
} catch (Exception e) {
wat = null;
int errorCode = (Integer) jsonObject.get("errcode");
String errorMsg = jsonObject.getString("errmsg");
log.info("获取网页授权凭证失败 errcode:"+errorCode+" errmsg:"+errorMsg);
}
}
return wat;
}
三、获取用户信息
/**
* 通过网页授权获取用户信息
*
* accessToken 网页授权接口调用凭证
* openId 用户标识
* @return SNSUserInfo
* @throws JSONException
*/
public static SNSUserInfo getSNSUserInfo(String accessToken, String openId) throws JSONException {
// 拼接请求地址
String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
// 通过网页授权获取用户信息
JSONObject jsonObject = new JSONObject(NetUtil.get(requestUrl)) ;
log.info("userinfo:"+jsonObject.toString());
if (null != jsonObject) {
try {
snsUserInfo = new SNSUserInfo();
// 用户的标识
snsUserInfo.setOpenId(jsonObject.getString("openid"));
// 昵称
snsUserInfo.setNickname(jsonObject.getString("nickname"));
// 性别(1是男性,2是女性,0是未知)
snsUserInfo.setSex((Integer) jsonObject.get("sex"));
// 用户所在国家
snsUserInfo.setCountry(jsonObject.getString("country"));
// 用户所在省份
snsUserInfo.setProvince(jsonObject.getString("province"));
// 用户所在城市
snsUserInfo.setCity(jsonObject.getString("city"));
// 用户头像
snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
// 用户特权信息
List<String> list = JSON.parseArray(jsonObject.getString("privilege"),String.class);
snsUserInfo.setPrivilegeList(list);
//与开放平台共用的唯一标识,只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
//snsUserInfo.setUnionid(jsonObject.getString("unionid"));
} catch (Exception e) {
log.info("ex:"+e);
snsUserInfo = null;
int errorCode = (Integer)jsonObject.get("errcode");
String errorMsg = jsonObject.getString("errmsg");
log.info("获取用户信息失败 errcode:"+errorCode+" errmsg:"+errorMsg);
}
}
return snsUserInfo;
}
四、获取code,获取网页授权access_token并获取用户信息
// 用户同意授权后,能获取到code
Map<String, String[]> params = request.getParameterMap();//针对get获取get参数
String[] codes = params.get("code");//拿到code的值
String code = codes[0];//code
log.info("用户同意授权获取到的code:"+code);
// 用户同意授权
if (!"authdeny".equals(code)) {
// 获取网页授权access_token
Oauth2Token oauth2Token = getOauth2AccessToken(appid, appSecret, code);
log.info("oauth2Token信息:"+JSON.toJSONString(oauth2Token));
// 网页授权接口访问凭证
String accessToken = oauth2Token.getAccessToken();
log.info("weixinIn-accessToken="+accessToken);
// 用户标识
String openId = oauth2Token.getOpenId();
log.info("weixinIn-openId="+openId);
// 获取用户信息
SNSUserInfo snsUserInfo = getSNSUserInfo(accessToken, openId);
snsUserInfo.setNickname(EmojiStringUtil.replaceEmoji(snsUserInfo.getNickname()));
log.info("用户信息openId:"+snsUserInfo.getOpenId()+", 用户微信昵称:"+snsUserInfo.getNickname());
//添加用户信息到数据库中
return "redirect:****"; //重定向到自己的业务逻辑页面
}else{
log.info("获取微信用户信息失败");
return null;
}
}else{
log.info("当前code为:" + code + ", 用户授权失败!");
return null;
}
五、相关实体类
网页授权信息
/**
网页授权信息
**/
public class Oauth2Token {
// 网页授权接口调用凭证
private String accessToken;
// 凭证有效时长
private int expiresIn;
// 用于刷新凭证
private String refreshToken;
// 用户标识
private String openId;
// 用户授权作用域
private String scope;
//省略getset方法
}
微信用户信息
/**
微信用户信息
**/
public class SNSUserInfo {
// 用户标识
private String openId;
// 用户昵称
private String nickname;
// 性别(1是男性,2是女性,0是未知)
private int sex;
// 国家
private String country;
// 省份
private String province;
// 城市
private String city;
// 用户头像链接
private String headImgUrl;
// 用户特权信息
private List<String> privilegeList;
//unionid
private String unionid;
//省略getset方法
}