前言
最近公司在做小程序开发,其中于微信号进行绑定的微信登录个人感觉不错,就想记录了下来
这篇文件就是讲实现微信登录小程序的相关使用
1.微信开发者工具(前端开发公具)
2.idea(后端开发)
3.jdk1.8(这个随意)
4.spring boot 项目(其实就是处理微信请求的接口,只要是接口,你随意)
流程介绍
注意啦:开发者服务器于开发者业务服务器是一样的(相当于 controller 和 service)
小程序->>小程序:wx.login()获取code(登录凭证)
小程序->>小程序:wx.getUserInfo()获取{ encryptedData, iv }
小程序->>开发者服务器: 发送请求(code,encryptedData, iv )
开发者服务器-->>微信接口服务: 发送请求(appid,secret,js_code,grant_type)
微信接口服务->>开发者服务器:响应数据(openId,session_key)
开发者服务器->>开发者业务服务器:解密数据(encryptedData, session_key, iv,UTF-8)
开发者服务器->>开发者业务服务器:进行业务处理(判断openId等是否存在数据库)
开发者服务器->>小程序:1.存在,返回登录成功
开发者服务器->>小程序:2.不存在,返回第一次登录需要绑定手机或注册 注:将微信信存入缓存后期使用(key)
小程序->>开发者服务器:发送请求(数据:手机号)
开发者服务器->>小程序:发送验证码
小程序->>开发者服务器:发送请求(数据:手机号,验证码,缓存key)
开发者服务器->>开发者业务服务器:校验手机验证码信息(是:下一步 否:结束)
开发者服务器->>开发者服务器:判断手机号是否存在
开发者服务器->>开发者业务服务器:1.存在:该手机号账户于微信缓存key的数据进行绑定
开发者服务器->>小程序:1.1 登录
开发者服务器->>开发者业务服务器:1.不存在
开发者服务器->>小程序:1.1 提示未注册
小程序->>开发者服务器:发起请求(注册用户数据)
开发者服务器->>开发者业务服务器:添加账户,账户于微信信息绑定
开发者服务器->>小程序:2.1 登录
html
js
/用户登陆
function userLogin() {
wx.checkSession({
success: function () {
//存在登陆态
},
fail: function () {
//不存在登陆态
//调用登录function 其实可以直接使用下面的
}
})
}
wxLogin: function (e) {
if (e.detail.userInfo == undefined) {
app.globalData.hasLogin = false;
util.showErrorToast('微信登录失败');
return;
}
var that = this
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var code = res.code// 登录凭证
//----------------------------------------------------------------------
//获取用户信息
wx.getUserInfo({
//当你获取用户信息的时候会弹出一个弹框是否允许授权
//这里点击允许出发的方法
success: function (res2) {
//that.globalData.userInfo = res2.userInfo
// 准备数据(下面的这些参数都是必须参数,请不要问为什么,看文档去吧)
var data = { encryptedData: res2.encryptedData, iv: res2.iv, code: code }
// 请求自己的服务器(在这里我结合promise封装了一下request请求,下面会把方法给大家分享一下)
var url ="/api-login-shiro/login/getWexInfo";
httpPost(url, data,
function (res3) {
console.log(res3);
})
},
fail: function (res2) {
app.globalData.hasLogin = false;
util.showErrorToast('微信登录失败');
}
});
//----------------------------------------------------------------------
}
})
}
cofing.js(小程序的配置文件)
const localhost = 'http://169.254.235.123';
const config = {
hostApi: `http://localhost:8200`, //你的域名
// hostApi: `${localhost}:9120`, //你的域名
hostFile: `${localhost}:8080/files/thumbnails/`, //文件
httpCode:{
success:'000000000'
},
navigationBar: {
backgroundColor: "#0D88FF",
textStyle: "white"
},
checkFrequency: { // 2: 日、3: 周、4: 月、5: 季、6: 年
2: { field: 'dayCount',label:'日'},
3: { field: 'weekCount', label:'周'},
4: { field: 'monthCount', label:'月'},
5: { field: 'quarterCount', label:'季'},
6: { field: 'yearCount', label:'年'}
}
}
module.exports = config
@PostMapping("/getWexInfo")
@ApiOperation(value = "根据加密文件 获取UnionID等信息")
@ApiImplicitParam(name = "wexDTO", value = "参数列表:" +
"
iv:iv 加密算法的初始向量 必填 " +
"
code:wx.login时获取,后期用于serssion_key 必填 " +
"
encryptedData:密文,被加密的数据 必填 "
, dataType = "WexDTO", required = true)
public ResultResponse getWexInfo(@Validated(WexDTO.ValidSave.class) @RequestBody WexDTO wexDTO, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return ResultResponse.wrap(bindingResult.getFieldError().getDefaultMessage());
}
ResultResponseresultResponse = this.accountService.getWexInfo(wexDTO);
if (resultResponse.getCode().equals(IfConstant.SERVER_SUCCESS.getCode())) {
Account account = (Account) resultResponse.getData();
AccountDTO accountDTO = new AccountDTO();
accountDTO.setMobilephone(account.getMobilephone());
accountDTO.setPassword(account.getPassword());
return loginQyForApp(accountDTO, bindingResult);
}
return resultResponse;
}
注意了:只是思路
这里缺少类:WexDTO,accountDTO,ResultResponse,
@Value("${appid}")
public String appid;
@Value("${secret}")
public String secret;
@Override
public ResultResponse getWexInfo(WexDTO wexDTO) {
try {
String url = "https://api.weixin.qq.com/sns/jscode2session";
Map requestUrlParam = new HashMap();
requestUrlParam.put("appid", appid); //开发者设置中的appId
requestUrlParam.put("secret", secret); //开发者设置中的appSecret
requestUrlParam.put("js_code", wexDTO.getCode()); //小程序调用wx.login返回的code
requestUrlParam.put("grant_type", "authorization_code"); //默认参数 authorization_code
String result = HttpUtils.sendPost(url,requestUrlParam);
if (null != result && !"".equals(result)) {
JSONObject returnInfoObject =JSON.parseObject(result);
String openid = returnInfoObject.getString("openid");
String session_key = returnInfoObject.getString("session_key");
String decryptResult = AesCbcUtil.decrypt(wexDTO.getEncryptedData(), session_key, wexDTO.getIv(), "UTF-8");
JSONObject userInfo = HttpUtils.getUserInfo(wexDTO.getEncryptedData(), session_key, wexDTO.getIv());
if (null != userInfo ) {
System.out.println(userInfo);
System.out.println(userInfo.get("openId"));
Account account=new Account();
account.setIsDelete(0);
account.setOpenid(userInfo.getString("openId"));
/*if(userInfo.getString("unionid")!=null){
account.setUnionid(userInfo.getString("unionid"));
}*/
//判断openId 是否在数据库中存在
if(accountMapper.selectCount(account)==1){
return ResultResponse.wrap(accountMapper.selectOne(account),IfConstant.SERVER_SUCCESS);
}else{
Long key=IdWorkerBuider.IDWORKER.nextId();
redisService.set(key.toString(),userInfo.toJSONString());
redisService.expire(key.toString(), VALID_MINUTE * 60);
return ResultResponse.wrap(key,IfConstant.USER_IS_RE_REGISTER);
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
这里缺少更多了
算了:不弄着这个
> 注:如果看到这里有啥疑问,可以留言哦