大体思路为:新起一个登录接口,放开拦截,登录接口使用小程序授权code获取openid,查询openId存在则进行登录成功,保存token并返回。没有则进行微信信息进行注册,保存token返回。
1.调整表结构。增加两个字段
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`user_name` varchar(30) NOT NULL COMMENT '用户账号',
`nick_name` varchar(30) NOT NULL COMMENT '用户昵称',
`user_type` varchar(2) DEFAULT '00' COMMENT '用户类型(00系统用户)',
`email` varchar(50) DEFAULT '' COMMENT '用户邮箱',
`phonenumber` varchar(11) DEFAULT '' COMMENT '手机号码',
`sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
`avatar` varchar(100) DEFAULT '' COMMENT '头像地址',
`password` varchar(100) DEFAULT '' COMMENT '密码',
`status` char(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`wxapp_openid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '小程序openid',
`unionid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '微信开放平台用户唯一标识',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户信息表';
2.新建一个微信授权登录接口
3.授权微信登录:根据code获取openId
4.根据unionid和openid获取用户信息userInfo 为空则增加用户信息代表注册。否则登录
5.登录成功,取得userInfo 组装token,并且返回。
6.小程序请求:http://192.168.10.142:8080/dev-api/system/user/login
入参和之前一样:
返回token
7.注册需要补全,这样后台也可以用账号密码登录
8.其他接口表头也要带access_token2
====================================其他代码===================
实体入参
@Data
public class LoginInfo implements Serializable {
private static final long serialVersionUID = -6201787321831974394L;
/**
* 登录code
*/
@NotBlank
private String loginCode;
/**
* 目标密文
*/
private String encryptedData;
/**
* 初始向量
*/
private String iv;
/**
* 来源
*/
private String source;
/**
*推荐用户id
*/
private Integer pid;
/**
* 登录方式【见枚举文档】
* */
private String type;
/**
* 人脸识别状态
*/
@SuppressWarnings("all")
@AllArgsConstructor
public static enum Type {
WeiXin("0000", "微信小程序"),
Android("0010", "点餐APP");
/**
* 状态
*/
public String status;
/**
* 描述
*/
public String desc;
public static Type info(String status) {
for (Type instance : values()) {
if (instance.status.equals(status)) {
return instance;
}
}
return WeiXin;
}
}
}
@PostMapping("/login")
public AjaxResult wxLogin(@RequestBody LoginInfo loginInfo) {
try {
// 获取信息
WxMaJscode2SessionResult session = null;
// 获取用户信息
WxMaUserInfo wxMaUserInfo = null;
// 筛选登录方式
switch (LoginInfo.Type.info(loginInfo.getType())){
// 微信登录
case WeiXin:
final WxMaService wxService = WxMaConfiguration.getMaService("wxa005e0000000000");
session = wxService.getUserService().getSessionInfo(loginInfo.getLoginCode());
wxMaUserInfo= wxService.getUserService().getUserInfo(session.getSessionKey(), loginInfo.getEncryptedData(), loginInfo.getIv());
/*
session = this.weiXinUtils.wxMaJscode2SessionResult(loginInfo.getLoginCode());
wxMaUserInfo =this.weiXinUtils.userInfo(session, loginInfo.getEncryptedData(), loginInfo.getIv());*/
break;
}
if (Objects.isNull(wxMaUserInfo)) {
return AjaxResult.error("登录失败!");
}
String unionid = org.apache.commons.lang3.StringUtils.isBlank(wxMaUserInfo.getUnionId()) ? null : session.getUnionid();
String openId = session.getOpenid();
SysUser userInfo = new SysUser();
//根据unionid和openid获取用户信息userInfo
userInfo = userService.selectWxUserByOpenId(openId);
if (Objects.isNull(userInfo)) {
userInfo = new SysUser();
//如果用户信息为空,创建一个用户信息 注册用户信息
String nickName=wxMaUserInfo.getNickName();
//用户名字为 手机号
userInfo.setUserName(nickName);
userInfo.setNickName(nickName);
userInfo.setWxappOpenid(openId);
userInfo.setUnionid(unionid);
userInfo.setPassword(SecurityUtils.encryptPassword("000000"));//密码默认为6个0
userInfo.setSex(wxMaUserInfo.getGender());
userInfo.setAvatar(wxMaUserInfo.getAvatarUrl());
userService.insertUser(userInfo);
userInfo = userService.selectWxUserByOpenId(openId);
if (Objects.isNull(userInfo)) {
return AjaxResult.error("登录失败!");
}
}
//组装token信息,保存token
LoginUser loginUser = new LoginUser();
loginUser.setOpenId(openId);
//假如有的话设置
loginUser.setSysUser(userInfo);
loginUser.setUserid(userInfo.getUserId());
Map<String, Object> map=tokenService.createToken(loginUser);
// 返回的用户信息
LoginSuccessDTO loginSuccessDTO = new LoginSuccessDTO();
loginSuccessDTO.setUserId(userInfo.getUserId().intValue());
loginSuccessDTO.setToken(map.get("access_token").toString());
loginSuccessDTO.setCheckMobile(Objects.isNull(userInfo.getPhonenumber())?LoginSuccessDTO.CHECK.EXIST.status : LoginSuccessDTO.CHECK.NO_EXIST.status);
return AjaxResult.success("登录成功!", loginSuccessDTO);
} catch (Exception e) {
return AjaxResult.error("出错了!", e);
}
}