package com.ruoyi.common.core.domain.entity;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
public class SysUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
@Excel(name = "登录名称")
private String userName;
@Excel(name = "用户名称")
private String nickName;
@Excel(name = "用户邮箱")
private String email;
@Excel(name = "手机号码")
private String phonenumber;
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
private String avatar;
private String password;
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
private String delFlag;
@Excel(name = "最后登录IP", type = Type.EXPORT)
private String loginIp;
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate;
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
private SysDept dept;
private List roles;
private Long[] roleIds;
private Long[] postIds;
private Long roleId;
public SysUser()
{
}
public SysUser(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public boolean isAdmin()
{
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId)
{
return userId != null && 1L == userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName()
{
return nickName;
}
public void setNickName(String nickName)
{
this.nickName = nickName;
}
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber()
{
return phonenumber;
}
public void setPhonenumber(String phonenumber)
{
this.phonenumber = phonenumber;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getAvatar()
{
return avatar;
}
public void setAvatar(String avatar)
{
this.avatar = avatar;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getLoginIp()
{
return loginIp;
}
public void setLoginIp(String loginIp)
{
this.loginIp = loginIp;
}
public Date getLoginDate()
{
return loginDate;
}
public void setLoginDate(Date loginDate)
{
this.loginDate = loginDate;
}
public SysDept getDept()
{
return dept;
}
public void setDept(SysDept dept)
{
this.dept = dept;
}
public List getRoles()
{
return roles;
}
public void setRoles(List roles)
{
this.roles = roles;
}
public Long[] getRoleIds()
{
return roleIds;
}
public void setRoleIds(Long[] roleIds)
{
this.roleIds = roleIds;
}
public Long[] getPostIds()
{
return postIds;
}
public void setPostIds(Long[] postIds)
{
this.postIds = postIds;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
}
}
修改后JavaBean
// 新增c002Id,以及它的get、set
private String c002Id;
public String getC002Id() {
return c002Id;
}
public void setC002Id(String c002Id) {
this.c002Id = c002Id;
}
修改mapper.xml
修改的selectUserByUserName方法
结果select c002_id from ctlm002
用户不存在就对了,目前使用的表内本来就没有admin
修改的selectMenuPermsByUserId方法修改为已有的用户名,提示密码错误(用户名不存在可以忽略不看)
接下来寻找密码校验
结果这就很尴尬,难怪还是提示密码错误,后端报错说没有找到对应数据,原来是rm表没有id为2的……
那我们给他默认为2就好了(手动狗头)
13:16:37.137 [http-nio-8088-exec-1] DEBUG c.r.s.m.S.selectUserByUserName - [debug,137] - ==> Preparing: select c002_id from ctlm002 where c002_var_user = ? 13:16:37.138 [http-nio-8088-exec-1] DEBUG c.r.s.m.S.selectUserByUserName - [debug,137] - ==> Parameters: 测试用户001(String) 13:16:37.157 [http-nio-8088-exec-1] DEBUG c.r.s.m.S.selectUserByUserName - [debug,137] - <== Total: 1 13:16:37.161 [http-nio-8088-exec-1] DEBUG c.r.s.m.S.selectMenuPermsByUserId - [debug,137] - ==> Preparing: select distinct m.perms from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_user_role ur on rm.role_id = ur.role_id left join sys_role r on r.role_id = ur.role_id where ur.user_id = 2 13:16:37.170 [http-nio-8088-exec-1] DEBUG c.r.s.m.S.selectMenuPermsByUserId - [debug,137] - ==> Parameters: 13:16:37.195 [http-nio-8088-exec-1] DEBUG c.r.s.m.S.selectMenuPermsByUserId - [debug,137] - <== Total: 79 13:16:37.196 [http-nio-8088-exec-1] WARN o.s.s.c.b.BCryptPasswordEncoder - [matches,126] - Empty encoded password 13:16:37.269 [http-nio-8088-exec-1] ERROR c.r.f.w.e.GlobalExceptionHandler - [handleRuntimeException,69] - 请求地址'/login',发生未知异常. com.ruoyi.common.exception.user.UserPasswordNotMatchException: 用户不存在/密码错误 at com.ruoyi.framework.web.service.SysLoginService.login(SysLoginService.java:82)
报错信息来看,用户名校验和菜单获取都没问题了,然后是密码校验
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
修改try代码块我的理解:触发了catch就肯定是try代码块的问题,那么用户名密码校验就只有可能是
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
这行代码,然后看它往下走的方法,找到这一对构造重载
如果用户名和密码能够在数据库匹配到数据则通过,没有匹配到直接抛出异常
try
{
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password, authentication.getAuthorities()));
}
结果
我还挺牛的(手动狗头)
接着我把try、catch全部注释掉了,然后系统给我报了一个空指针异常
try会给我设置好loginUser的值,我注释掉了自然不会有
// try
// {
// // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
// authentication = authenticationManager
// .authenticate(new UsernamePasswordAuthenticationToken(username, password, authentication.getAuthorities()));
// }
// catch (Exception e)
// {
// if (e instanceof BadCredentialsException)
// {
// AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
// throw new UserPasswordNotMatchException();
// }
// else
// {
// AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
// throw new ServiceException(e.getMessage());
// }
// }
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
// 这里,loginUser的值从authentication中获取,这里默认为空
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
手动设置token条件很明显它不打算让我set!(手动捂脸)
SysUser sysUser = userService.selectUserByUserName(username);
sysUser.setUserName(username);
LoginUser loginUser = new LoginUser();
loginUser.setUserId(sysUser.getUserId());
loginUser.setUser(sysUser);
// 生成token
return tokenService.createToken(loginUser);
结果我这边先给了loginUser的id,然后报错还需要username,然后我将username设置到sysUser中去,另外由于我修改过userMapper的selectUserByUserName方法,还需要将username赋值给sysUser
然后!
修改菜单(路由获取)方法成功登入
这里没有菜单,找到对应位置
@GetMapping("getRouters")
public AjaxResult getRouters()
{
// Long userId = SecurityUtils.getUserId();
List menus = menuService.selectMenuTreeByUserId(2L);
return AjaxResult.success(menuService.buildMenus(menus));
}
新增id、密码校验(使用了md5密码校验)成功!
mapper.xml
mapper
int login(String md5); String getMd5(String c002PasswordId);
service
int login(String md5); String getMd5(String c002Id,String password);
serviceImpl
@Override
public int login(String md5) {
return userMapper.login(md5);
}
@Override
public String getMd5(String c002Id, String password) {
return userMapper.getMd5(password + c002Id);
}
登录方法逻辑
SysUser sysUser = userService.selectUserByUserName(username);
if (sysUser == null) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
String md5 = userService.getMd5(sysUser.getC002Id(), password);
int count = userService.login(md5);
if (count != 1) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
// LoginUser loginUser = (LoginUser) authentication.getPrincipal();
// recordLoginInfo(loginUser.getUserId());
sysUser.setUserName(username);
LoginUser loginUser = new LoginUser();
loginUser.setUserId(sysUser.getUserId());
loginUser.setUser(sysUser);
// 生成token
return tokenService.createToken(loginUser);
项目要求密码需要通过md5加密,因此里面多写了一个md5值的获取
增加当用户名不存在或密码错误时的异常抛出



