写在前面的话
H5授权获取用户信息,这次采用了比较流行的wxJava包 /binary/weixin-java-tools
需要一些配置
1、config 里需要两个文件
package com.xxx.common.configuration;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.stream.Collectors;
/**
* 类名称:WxMpConfiguration
*
* 描述:wechat mp configuration
* 创建时间: 2022-09-17 13:20:37
*/
@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
private final WxMpProperties properties;
/**
* 微信服务类
*
* @return {@link WxMpService }
* @date 2022-09-17 13:20:38
*/
@Bean
public WxMpService wxMpService() {
// 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
if (configs == null) {
throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
}
WxMpService service = new WxMpServiceImpl();
service.setMultiConfigStorages(configs
.stream().map(a -> {
WxMpDefaultConfigImpl configStorage;
configStorage = new WxMpDefaultConfigImpl();
configStorage.setAppId(a.getAppId());
configStorage.setSecret(a.getSecret());
configStorage.setToken(a.getToken());
configStorage.setAesKey(a.getAesKey());
return configStorage;
}).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
return service;
}
}
package com.xxx.common.configuration;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* 类名称:WxMpProperties
*
* 描述:wechat mp properties
* 创建时间: 2022-09-17 13:21:19
*/
@Data
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
/**
* 是否使用redis存储access token
*/
private boolean useRedis;
/**
* redis 配置
*/
private RedisConfig redisConfig;
@Data
public static class RedisConfig {
/**
* redis服务器 主机地址
*/
private String host;
/**
* redis服务器 端口号
*/
private Integer port;
/**
* redis服务器 密码
*/
private String password;
/**
* redis 服务连接超时时间
*/
private Integer timeout;
}
/**
* 多个公众号配置信息
*/
private List<MpConfig> configs;
@Data
public static class MpConfig {
/**
* 设置微信公众号的appid
*/
private String appId;
/**
* 设置微信公众号的app secret
*/
private String secret;
/**
* 设置微信公众号的token
*/
private String token;
/**
* 设置微信公众号的EncodingAESKey
*/
private String aesKey;
}
/**
* 重写toString
*
* @return {@link String }
* @date 2022-09-17 13:21:19
*/
@Override
public String toString() {
return JSONUtil.toJsonStr(this);
}
}
2、配置文件内容
#wxjava(appid,appsecret,接口配置里的Token值,接口配置里的EncodingAESKey值)
wx.mp.useRedis=false
wx.mp.configs[0].appId=11111
wx.mp.configs[0].secret=222222
wx.mp.configs[0].token=
wx.mp.configs[0].aesKey=
一、跳转
原理,没有session就构建一个要回跳的地址并存起来,生成一个新的跳转地址
if (httpServletRequest.getSession().getAttribute("wechat_user") == null) {
// 定义要跳回的地址
String scheme = httpServletRequest.getScheme(); // 协议 如:https
//String remoteHost = httpServletRequest.getRemoteHost(); // 网址 如:127.0.0.1
String remoteHost = "javaxq.xxx.cc"; // 这里先写死,上边获取的为本地ip
String referer = scheme + "://" + remoteHost + "/#/answer?sn=" + id;
// 追加部分参数
Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
if (parameterMap.size() > 0) {
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String key = entry.getKey();
String[] value = entry.getValue();
if (value.length > 0) {
if (StringUtils.isNotBlank(value[0])) {
referer += "&" + key + "=" + value[0];
}
}
}
}
// 写入session
httpServletRequest.getSession().setAttribute("target_url", referer);
// 构建要跳转的地址
String jumpUrl = scheme + "://" + remoteHost + "/api/answer/oauth_callback";
// 构建微信授权的跳转地址
referer = wxMpService.getOAuth2Service().buildAuthorizationUrl(jumpUrl, "snsapi_userinfo", null);
// 返回要跳转的信息,这里你可以自行修改为返回上边的地址
this.setAction(answerVo, RStatus.REDIRECT.getCode(), referer);
return answerVo;
}
回调
原理,接收code,获取用户信息,写入session,读取session里的跳转地址进行跳转
/**
* 微信授权回调
*
* @param code
* @param response 响应
* @return {@link String }
* @date 2022-09-17 13:31:26
*/
@GetMapping(value = "/oauth_callback")
public String oauth(String code, HttpServletResponse response) throws WxErrorException, IOException {
// 用code获取accessToken,这里的accessToken指的是单个用户授权的accessToken
WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
// 用accessToken获取用户信息
WxOAuth2UserInfo userInfo = wxMpService.getOAuth2Service().getUserInfo(accessToken, "zh_CN");
if (userInfo != null) {
// 写入 session->wechat_user
Map<String, String> userInfoMap = new HashMap<>();
userInfoMap.put("open_id", userInfo.getOpenid());
userInfoMap.put("nick_name", userInfo.getNickname());
httpServletRequest.getSession().setAttribute("wechat_user", userInfoMap);
// 跳转
String targetUrl = (String) httpServletRequest.getSession().getAttribute("target_url");
if (StringUtils.isNotBlank(targetUrl)) {
response.sendRedirect(targetUrl);
}
//response.sendRedirect(userInfo.get);
}
// 获取 target_url 并进行跳转
return userInfo.toString();
}