之前介绍了两种小程序获取用户信息的写法,其中第二种需要后端配合完成。
后端我使用了一个第三方的 jar 包:
我使用的是 2.9.6.BETA 版本。
这个版本提供了通过微信参数解析用户信息的方法,只要在配置文件中把微信小程序的信息配置完成就可以直接使用,非常方便。
直接看后台获取用户信息和生成第三方token 的方法,这里的生成方式是直接使用 java 自带的方法:
@Autowired
private RedisUtil redisUtil;
@Autowired
private WxMaService wxService;
@RequestMapping(value = "/login_status", method = RequestMethod.GET)
public String getLoginStatus(@RequestParam(value = "code") String code,
@RequestParam(value = "signature") String signature,
@RequestParam(value = "rawData") String rawData,
@RequestParam(value = "encryptedData") String encryptedData,
@RequestParam(value = "iv") String iv) throws WxErrorException {
if(StringUtils.isEmpty(code)) {
return "无效的code";
}else {
//存在有效的 code
System.out.println("这里请求了一次code==========" + code);
WxMaJscode2SessionResult session = this.wxService.getUserService().getSessionInfo(code);
String sessionKey = session.getSessionKey();
//通过openId sessionKey 生成3rd session 返回给客户端小程序
String accessToken = UUID.randomUUID().toString();
// 用户信息校验
if (!this.wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
return "用户信息校验失败";
}
// 解密用户信息
WxMaUserInfo userInfo = this.wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
System.out.println(userInfo);
System.out.println("accessToken : " + accessToken);
redisUtil.set("asdfKevin", accessToken, 180L);
return accessToken;
}
其中的 wxService 是上述 jar 自带的内容,redisUtil 是我自己封装的 redis 的读取工具类,比较简单就不说了。
代码逻辑非常简单,直接看就能看懂,最后 token 存到了 redis 中,备用。
另外 wxService 需要的两个配置类,代码如下:
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
@ConfigurationProperties(prefix = "wechat.miniapp")
@Data
public class WxMaProperties {
private String appid;
private String secret;
private String token;
private String aesKey;
private String msgDataFormat;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}
import javax.servlet.Filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.kevin.crystal.filter.KevinTokenFilter;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
@Configuration
@ConditionalOnClass(WxMaService.class)
@EnableConfigurationProperties(WxMaProperties.class)
public class WxMaConfiguration {
@Autowired
private WxMaProperties properties;
@Bean
@ConditionalOnMissingBean
public WxMaConfig config() {
WxMaInMemoryConfig config = new WxMaInMemoryConfig();
config.setAppid(this.properties.getAppid());
config.setSecret(this.properties.getSecret());
config.setMsgDataFormat(this.properties.getMsgDataFormat());
return config;
}
@Bean
@ConditionalOnMissingBean
public WxMaService wxMaService(WxMaConfig config) {
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config);
return service;
}
@Bean
public Filter kevinTokenFilter() {
System.out.println("----------------test token filter-----------------");
return new KevinTokenFilter();
}
@Bean
public FilterRegistrationBean tokenFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(kevinTokenFilter());
registration.addUrlPatterns("/api/*");
// registration.addInitParameter("", "");
registration.setName("tokenFilter");
return registration;
}
}
其中java 代码中读取的配置文件需要正确配置小程序的 app id 和 app secret 。至此,后台获取微信用户的信息的方法就介绍完了。
如果你是源码复制,发现一个东西 KevinTokenFilter,聪明的你一猜就知道,这个就是我之前提到的过滤小程序后续请求中是否存在自定义token 的方法啦。下一篇介绍使用 filter 过滤请求头的一种实现方法。