微信小程序及Java后台测试登录
文章目录
一、使用的工具以及开发环境
微信 · 客户端
- 微信开发者工具 v1.02.1901230
- 新建快捷项目
后台 · 服务端
- SSM 框架 / SpringBoot +Mybatis
- JDK 1.8 、tomcat 9.0
二、微信端登录代码。
- 查看快捷项目模板 app.js 文件中的有关登录的内容
第一种方式,使用wx.getUserInfo直接获取微信头像,昵称。
小程序启动之后,在 app.js 定义的 App 实例的 onLaunch 回调会被执行。onLaunch 中的三个接口
- wx.login 接口,第二种方法细讲。
- wx.getSetting 接口
也就是说,在调用这个接口的返回值是判断用户是否进行授权的。
其中这个函数中有三个回调的方法。
在回调方法中进行授权的判断
- wx.getUserInfo 接口
将获得以下的信息
第二种方式:wx.login,
- 获取更多的信息的,如微信用户的openid。
通过这种方式呢,首先要明确和第一种的区别,wx.login 是属于微信登录,而wx.getUserInfo属于获取用户的信息,前者方便后台处理逻辑,后者方便前台展示。
标准的登录步骤
1、小程序通过wx.login()接口从微信官方服务器获取用户code
注意:wx.login()接口是不会弹出授权窗口。
2、小程序把wx.login() 得到的code和AppId+AppSecret传给开发者服务器
注意:两种方式,2.1、微信端直接访问请求获取openid。2.2、后台访问请求获取openid
3、服务器经过一系列的处理,把seesion_key+open_id取出来,换成我们自定义的内容,譬如userid
- 紧接着,确定我们后台要存储用户的那些信息,我是把用户的唯一主键与openid 结合起来使用的,这样减少一个字段,而且还能够确定登录用户的唯一性。
- wx.login() 的两个属性值一个是code,一个是errMsg
- AppId+AppSecret 需要登录微信公众平台的基本配置页显示,APPID是公开的,而开发者密码需要管理员手动操作。
说了这么多,还是不知道客户端怎么写的看这里。
onLoad: function () {
var that = this;
// 查看是否授权
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
wx.getUserInfo({ // 获取用户的信息
success: function (res) {
var userInfo = res;
// 用户已经授权过,不需要显示授权页面,所以不需要改变 isHide 的值
wx.login({ // 用户登录
success: res => {
console.log("用户的code:" + res.code);
// 传给后台,再经过解析获取用户的 openid
wx.request({
url: 'http://localhost:8080/wx/wx/addUser',
method: 'GET',
data: {
code: res.code,
encryptedData: userInfo.encryptedData,
iv: userInfo.iv
},
header: {
'content-type': 'application/json'
},
success: function (res) {
// this.globalData.userInfo = JSON.parse(res.data);
console.log('测试后台响应内容')
console.log(res)
// wx.setStorageSync('openId', res.data.openId);
},
fail: res => {
console.log('访问后台授权失败')
},
complete: function (res) {
console.log('请求后台测试登录完成')
}
})
}
});
}
});
} else {
// 用户没有授权
// 改变 isHide 的值,显示授权页面
that.setData({
isHide: true
});
}
}
});
}
- 上面代码中,有一处需要注意的是 wx.request的url,官方是这样说明的:
- 为了使测试代码正常进行,进行如下操作:
详细的后台代码。
搭建后台代码,设计存储数据数据库(除去存储微信用户的数据表,还要有业务处理表)
客户端授权处理:只有授权的用户,才可以进行数据存储,以及业务处理。
- 先导包。大家可以在仓库找到最新的版本。
<!-- 小程序解析用户的详细信息 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<!-- 小程序解析用户的详细信息 -->
或者是
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>3.3.4.B</version>
</dependency>
注意
weixin-java-miniapp.jar 包中已经封装好了获取微信信息的方法,只需要传递相应的参数即可。而且后台会自动导入前一个 jar 包。所以我们这里简单的介绍一下第二个 Jar 包的使用,主要使用的是第一个 Jar 包。
bcprov-jdk16.jar
- 获取用户的唯一标识 openid
- 解析用户信息,获取更多的用户信息
步骤总结:
1.首先,根据的用户的登录凭证code,判断用户登录。
2.根据小程序的 appid与secret,获取用户的 openid 与 session_key
3.根据 encryptedData、iv 以及得到的 session_key 获取更多的用户信息。
weixin-java-miniapp.jar (建议使用 SpringBoot 开发)
这个可就简单了,如下:
- 在上面的步骤中,我们仅仅使用了 WxMaService,通过 @Configuration 和@Bean注入到了Spring容器中,通过@Autowire 注入到Controller中,但是我们需要的Appid与Secret 是没有加入到 WxMaService 中的,所以需要对上述内容进行修改。
SpringBoot 项目修改
- @ConfigurationProperties(prefix = “wechat.wx”) 读取配置文件中的信息
// 编写一个 WechatMpProperties 负责读取配置信息
@Data
@ConfigurationProperties(prefix = "wechat.wx")
public class WxMaProperties {
private List<Config> configs;
@Data
public static class Config {
/**
* 设置微信小程序的appid
*/
private String appid;
/**
* 设置微信小程序的Secret
*/
private String secret;
/**
* 设置微信小程序消息服务器配置的token
*/
private String token;
/**
* 设置微信小程序消息服务器配置的EncodingAESKey
*/
private String aesKey;
/**
* 消息格式,XML或者JSON
*/
private String msgDataFormat;
}
}
- 接着编写 WechatMpConfiguration 配置类,WxMaService 等配置。
// 配置 WxMaService
// 配置 WxMaConfigStorage 配置将存储获取到的 WechatMpProperties 参数信息。
// 配置 WxMaMessageRouter 消息路由设置:分为模板、图片、文本、二维码。
@Component
public class WxMpServiceFactory {
private static WxMaService wxMaService;
private static WxMaInMemoryConfig wxMaConfigStorage;
private static WxMaMessageRouter router = new WxMaMessageRouter(getInstance());
private WxMpServiceFactory() {
}
// 产生WxmaService实例
@Bean
public static WxMaService getInstance() {
if(wxMaConfigStorage == null){
wxMaConfigStorage = new WxMaInMemoryConfig();
wxMaConfigStorage.setAppid(WXMPConfig.APPID);
wxMaConfigStorage.setSecret(WXMPConfig.APPSECRET);
wxMaConfigStorage.setToken(WXMPConfig.TOKEN);
wxMaConfigStorage.setAesKey(WXMPConfig.ENCODINGAESKEY);
wxMaConfigStorage.setMsgDataFormat(WXMPConfig.MSGDATAFORMAT);
}
if (wxMaService == null) {
wxMaService = new WxMaServiceImpl();
wxMaService.setWxMaConfig(wxMaConfigStorage);
}
return wxMaService;
}
public static WxMaInMemoryConfig getWxMaConfigStorage() {
return wxMaConfigStorage;
}
public static void setWxMaConfigStorage(WxMaInMemoryConfig wxMpConfigStorage) {
WxMpServiceFactory.wxMaConfigStorage = wxMpConfigStorage;
}
public static void setInstance(WxMaService wxMaService) {
WxMpServiceFactory.wxMaService = wxMaService;
}
public static WxMaMessageRouter getRouter() {
return router;
}
public static void setRouter(WxMaMessageRouter router) {
WxMpServiceFactory.router = router;
}
}
- @RequestBody 与 @ResponseBody 中返回的 JSON设置
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
/**
* @author RobertChao
*/
public class JsonUtils {
private static final ObjectMapper JSON = new ObjectMapper();
static {
JSON.setSerializationInclusion(Include.NON_NULL);
JSON.configure(SerializationFeature.INDENT_OUTPUT, Boolean.TRUE);
}
public static String toJson(Object obj) {
try {
return JSON.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
调用 : return JsonUtils.toJson(session);
简单Web项目修改
- 使用工厂的方式,将内容加到Spring的Bean 中。
- 直接使用工厂中的变量
使用 过程中遇到的问题
- 问题一,工厂中加载 WxMaService 的属性内容的时候要求 httpclient 版本在 4.4 以上。
- 报了一个错误为java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy,
TrustStrategy这个类找不到。
经查看这个TrustStrategy位于org.apache.http.ssl.TrustStrategy包属于httpcore-4.4.jar包底下,或者更高版本底下,而4.4以下的版本并没有这个类,所以产生这个错误的原因就是项目底下引用了低版本的httpcore的jar包,而这个httpcore的jar包又是跟httpclient的jar包相关联的,所以httpclient的jar包也要用较高版本。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
- 问题二:wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);请求用户身份的详细资源的时,对 json 格式的要求比较严格。
认真书写 Json 内容,对待每一处 格式要求。
问题三:暂未解决,希望有大神看到能帮助。
代码中会调用WxMpServiceImpl.initHttp()方法,IdleConnectionMonitorThread线程(IdleConnectionMonitorThread类)负责监控httpclient中的连接,进行清理操作。
暂时没有解决日志出现这个的问题。
评论留下联系方式,发源码。