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;
/**
* 用户对象 sys_user
*
* @author ruoyi
*/
public class SysUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 用户ID */
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/** 部门ID */
@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;
/** 帐号状态(0正常 1停用) */
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 最后登录IP */
@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<SysRole> roles;
/** 角色组 */
private Long[] roleIds;
/** 岗位组 */
private Long[] postIds;
/** 角色ID */
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<SysRole> getRoles()
{
return roles;
}
public void setRoles(List<SysRole> 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();
}
}
// 新增c002Id,以及它的get、set
private String c002Id;
public String getC002Id() {
return c002Id;
}
public void setC002Id(String c002Id) {
this.c002Id = c002Id;
}
<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResultC002">
<include refid="selectUserVoC002"/>
where c002_var_user = #{userName}
select>
<resultMap type="SysUser" id="SysUserResultC002">
<result property="c002Id" column="c002_id" />
resultMap>
<sql id="selectUserVoC002">
select c002_id
from ctlm002
sql>
用户不存在就对了,目前使用的表内本来就没有admin
修改为已有的用户名,提示密码错误(用户名不存在可以忽略不看)
接下来寻找密码校验
<select id="selectMenuPermsByUserId" parameterType="Long" resultType="String">
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 = 1
select>
这就很尴尬,难怪还是提示密码错误,后端报错说没有找到对应数据,原来是rm表没有id为2的……
那我们给他默认为2就好了(手动狗头)
<select id="selectMenuPermsByUserId" parameterType="Long" resultType="String">
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
select>
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;
}
我的理解:触发了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();
很明显它不打算让我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<SysMenu> menus = menuService.selectMenuTreeByUserId(2L);
return AjaxResult.success(menuService.buildMenus(menus));
}
成功!
mapper.xml
<select id="getMd5" parameterType="String" resultType="String">
select md5(#{c002PasswordId})
select>
<select id="login" parameterType="String" resultType="int">
select count(*) from sys312 where s312_var_pass = #{md5}
select>
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值的获取
增加当用户名不存在或密码错误时的异常抛出