引进微信PC登录和微信公众号登录功能
1.微信PC登录
需要前往微信开放平台注册一个账号,并创建一个网站应用,成功后这个拿到这个网站应用的appid与secrect
String APPID=(String) weixinLogin.get("appid");
//CommonConstants.contextPath 为项目前缀
String REDIRECT_URI=
URLEncoder.encode(CommonConstants.contextPath+"/app/weixinAuthLogin");
//pc网页微信登录的scope类型为snsapi_login 微信公众号的scope类型为snsapi_userinfo
String redirectUrl="redirect:https://open.weixin.qq.com/connect/qrconnect?appid="+APPID+"&redirect_uri="+REDIRECT_URI+"&response_type=code&scope=snsapi_login&state=wxPcLogin#wechat_redirect";
以下为微信回调授权处理代码
public JSONObject weixinAuthLogin(WeixinAuth weixinAuth) throws Exception {
/**
* 返回值
*/
JSONObject returnJson = new JSONObject();
/**
* 1.获取access_token
*/
JSONObject tokenResp = getAccessToken(weixinAuth);
String accessToken = tokenResp.getString("access_token");
String openId = tokenResp.getString("openid");
/**
* 2.校验token是否有效
*/
//接口请求参数
Map<String, Object> authParam = new HashMap<>();
authParam.put("access_token", accessToken);
authParam.put("openid", openId);
//发送请求,获取返回值,校验access_token
refreshAccessToken(authParam);
/**
* 3.校验通过,获取用户信息
*/
//用户信息的参数与校验参数相同
JSONObject userInfoResponse = getUserInfo(authParam);
returnJson.putAll(userInfoResponse);
returnJson.put("whetherLogin", false);
return returnJson;
}
/**
* 获取access_token,并校验返回值
* @param weixinAuth
* @return
* @throws Exception
*/
private JSONObject getAccessToken(WeixinAuth weixinAuth) throws Exception {
Map<String, Object> accessTokenParam = new HashMap<>();
accessTokenParam.put("appid", 你的wxAppId);
accessTokenParam.put("secret", 你的wxAppSecret);
accessTokenParam.put("code", weixinAuth.getCode());
accessTokenParam.put("grant_type", "authorization_code");
String param = MapUtils.getParamByMap(accessTokenParam);
//发送请求,获取返回结果
String tokenResponseStr =
HttpRequestUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token", param);
if (StringUtils.isBlank(tokenResponseStr) || !tokenResponseStr.startsWith("{")) {
logger.error("-------请求微信access_token接口错误:-------" + tokenResponseStr);
throw new Exception("请求微信access_token接口错误");
}
//取出access_token 与 openId
JSONObject tokenResp = JSONObject.parseObject(tokenResponseStr);
String openId = tokenResp.getString("openid");
if (StringUtils.isBlank(openId)) {
logger.error("-------请求微信access_token接口返回值错误:-------" + tokenResponseStr);
throw new Exception("请求微信access_token接口返回值错误");
}
return tokenResp;
}
/**
* 校验token是否有效
* @param authParam
* @throws Exception
*/
private void refreshAccessToken(Map<String, Object> authParam) throws Exception {
//发送请求,获取返回值
String authResponseStr =
HttpRequestUtil.sendGet("https://api.weixin.qq.com/sns/auth", MapUtils.getParamByMap(authParam));
// 判断返回值是否正确
if (StringUtils.isBlank(authResponseStr) || !authResponseStr.startsWith("{")) {
logger.error("-------请求微信auth接口返回值错误:-------" + authResponseStr);
throw new Exception("请求微信auth接口返回值错误");
}
JSONObject authResponse = JSONObject.parseObject(authResponseStr);
// 判断token是否有效,如果token失效,重新拉取access_token
if (!StringUtils.equals("ok", authResponse.getString("errmsg"))) {
// refresh_token接口参数
Map<String, Object> refreshTokenParam = new HashMap<>();
refreshTokenParam.put("appid", wxAppId);
refreshTokenParam.put("grant_type", "refresh_token");
refreshTokenParam.put("refresh_token", "REFRESH_TOKEN");
// 回去返回值
String refreshTokenResponseStr =
HttpRequestUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/refresh_token", MapUtils.getParamByMap(refreshTokenParam));
// 判断返回值的结果是否出错
if (StringUtils.isBlank(refreshTokenResponseStr) || !refreshTokenResponseStr.startsWith("{")) {
logger.error("-------请求微信refresh_token接口错误:-------" + refreshTokenResponseStr);
throw new Exception("请求微信refresh_token接口错误");
}
JSONObject refreshTokenResponse = JSONObject.parseObject(refreshTokenResponseStr);
if (StringUtils.isBlank(refreshTokenResponse.getString("refresh_token"))) {
logger.error("-------请求微信refresh_token接口返回值错误:-------" + refreshTokenResponseStr);
throw new Exception("请求微信refresh_token接口返回值错误");
}
// 重新设置access_token
authParam.put("access_token", refreshTokenResponse.getString("refresh_token"));
}
}
/**
* 校验通过,获取用户信息
* @param authParam
* @return
* @throws Exception
*/
private JSONObject getUserInfo(Map<String, Object> authParam) throws Exception {
/**
* 3.校验通过,获取用户信息
*/
//用户信息的参数与校验参数相同
String userInfoResponseStr =
HttpRequestUtil.sendGet("https://api.weixin.qq.com/sns/userinfo", MapUtils.getParamByMap(authParam));
//判断返回值是否正确
if (StringUtils.isBlank(userInfoResponseStr) || !userInfoResponseStr.startsWith("{")) {
logger.error("-------请求微信userinfo接口错误:-------" + userInfoResponseStr);
throw new Exception("请求微信userinfo接口错误");
}
JSONObject userInfoResponse = JSONObject.parseObject(userInfoResponseStr);
if (StringUtils.isBlank(userInfoResponse.getString("openid"))) {
logger.error("-------请求微信userinfo接口返回值错误:-------" + userInfoResponseStr);
throw new Exception("请求微信userinfo接口返回值错误");
}
return userInfoResponse;
}
以上代码可同时用于pc和微信公众号回调获取用户信息,需要注意的是,PC微信登录的appid与secrect与微信公众号的appid和appSecrect不同
PC微信的授权为(scope=snsapi_login)
https://open.weixin.qq.com/connect/qrconnect?appid="+APPID+"&redirect_uri="+REDIRECT_URI+"&response_type=code&scope=snsapi_login&state=wxPcLogin#wechat_redirect
微信公众号的授权为(scope=snsapi_userinfo)
https://open.weixin.qq.com/connect/qrconnect?appid="+APPID+"&redirect_uri="+REDIRECT_URI+"&response_type=code&scope=snsapi_userinfo&state=wxPcLogin#wechat_redirect