• ruoyi框架使用自定义用户表登录


    背景

    有的时候我们做框架升级或改造的时候,需要用到原来的部分表,比如只是用ruoyi的框架,然后登录的用户逻辑还是想用自己的表,那么接下来这边文章将介绍修改逻辑。

    修改教程

    1、SysLoginController.java

    大家找到这个login方法,这是controller的入口。

    1. /**
    2. * 登录方法
    3. *
    4. * @param loginBody 登录信息
    5. * @return 结果
    6. */
    7. @PostMapping("/login")
    8. public AjaxResult login(@RequestBody LoginBody loginBody)
    9. {
    10. // 退出接口查看LogoutSuccessHandlerImpl.onLogoutSuccess
    11. AjaxResult ajax = AjaxResult.success();
    12. // 生成令牌,修改这个map返回自己的表的用户对象。
    13. // 如果这里不处理其余的逻辑就不需要修改,因为我这里要手动写入自己的日志
    14. Map map = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
    15. loginBody.getUuid());
    16. LoginUser loginUser = (LoginUser)map.get("loginUser");
    17. loginUser.setLanguage(loginBody.getLanguage());
    18. bsOperateLogV2Service.createLoginLog(String.valueOf(loginUser.getUserId()),
    19. loginUser.getUsername(),1,String.valueOf(loginUser.getDeptId()));
    20. ajax.put(Constants.TOKEN, map.get("token"));
    21. return ajax;
    22. }

    2、SysLoginService.java

    这里有一些验证,比如验证码,用户是否存在等,大家点击进入到loginPreCheck方法中,把查询用户修改为自己的表查询,然后把没有用的逻辑注释掉。

    1. /**
    2. * 登录验证
    3. *
    4. * @param username 用户名
    5. * @param password 密码
    6. * @param code 验证码
    7. * @param uuid 唯一标识
    8. * @return 结果
    9. */
    10. public Map login(String username, String password, String code, String uuid)
    11. {
    12. // 验证码校验
    13. validateCaptcha(username, code, uuid);
    14. // 登录前置校验
    15. loginPreCheck(username, password);
    16. // 用户验证
    17. Authentication authentication = null;
    18. try
    19. {
    20. UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
    21. AuthenticationContextHolder.setContext(authenticationToken);
    22. // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
    23. authentication = authenticationManager.authenticate(authenticationToken);
    24. }
    25. catch (Exception e)
    26. {
    27. if (e instanceof BadCredentialsException)
    28. {
    29. //AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
    30. throw new UserPasswordNotMatchException();
    31. }
    32. else
    33. {
    34. //AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
    35. throw new ServiceException(e.getMessage());
    36. }
    37. }
    38. finally
    39. {
    40. AuthenticationContextHolder.clearContext();
    41. }
    42. //AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    43. LoginUser loginUser = (LoginUser) authentication.getPrincipal();
    44. //recordLoginInfo(loginUser.getUserId());
    45. Map map = new HashMap<>();
    46. map.put("token",tokenService.createToken(loginUser));
    47. map.put("loginUser",loginUser);
    48. // 生成token
    49. return map;
    50. }
    51. /**
    52. * 登录前置校验
    53. * @param username 用户名
    54. * @param password 用户密码
    55. */
    56. public void loginPreCheck(String username, String password)
    57. {
    58. // 用户名或密码为空 错误
    59. if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
    60. {
    61. AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
    62. throw new UserNotExistsException();
    63. }
    64. // 密码如果不在指定范围内 错误
    65. // if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
    66. // || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
    67. // {
    68. // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
    69. // throw new UserPasswordNotMatchException();
    70. // }
    71. // // 用户名不在指定范围内 错误
    72. // if (username.length() < UserConstants.USERNAME_MIN_LENGTH
    73. // || username.length() > UserConstants.USERNAME_MAX_LENGTH)
    74. // {
    75. // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
    76. // throw new UserPasswordNotMatchException();
    77. // }
    78. // // IP黑名单校验
    79. // String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
    80. // if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
    81. // {
    82. // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
    83. // throw new BlackListException();
    84. // }
    85. }

    3、loadUserByUsername方法

    大家找到UserDetailsServiceImpl.loadUserByUsername方法,这是核心。

    1. @Override
    2. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    3. {
    4. Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
    5. // 这是自己的页面输入的密码,没有加密,比如123456
    6. String inputPassword = usernamePasswordAuthenticationToken.getCredentials().toString();
    7. // 这里是自定义的表查询,用户和密码验证,如果还有其他的验证都可以在这里进行添加
    8. LambdaQueryWrapper wrapper = new LambdaQueryWrapper()
    9. .eq(BladeUserV2DO::getAccount,username)
    10. //PasswordUtil是自己的加密工具,你用什么加密就保持原来的就行
    11. .eq(BladeUserV2DO::getPassword, PasswordUtil.encrypt(inputPassword))
    12. .eq(BladeUserV2DO::getIsDeleted,0);
    13. // 这里写自己的登录验证逻辑
    14. BladeUserV2DO bladeUserV2DO = bladeUserV2Mapper.selectOne(wrapper);
    15. // SysUser user = userService.selectUserByUserName(username);
    16. if (StringUtils.isNull(bladeUserV2DO))
    17. {
    18. log.info("登录用户:{} 不存在.", username);
    19. throw new UserPasswordNotMatchException();
    20. }
    21. BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    22. // 这里一定要把加密后的密码放进去,后面的验证中会一直用这个密码
    23. // 这个是123456加密后的密码,这里给框架都是完全通过的密码,
    24. // 因为我们在方法开始的时候自己进行密码验证,能走到这里都是验证通过的
    25. bladeUserV2DO.setPassword(passwordEncoder.encode(inputPassword));
    26. passwordService.validate(bladeUserV2DO);
    27. return createLoginUser(bladeUserV2DO);
    28. }
    29. public UserDetails createLoginUser(BladeUserV2DO bladeUserV2DO)
    30. {
    31. BladeUserRespVo bladeUserRespVo = bladeUserV2Mapper.getBladeUserInfo(bladeUserV2DO.getId());
    32. SysUser user = new SysUser();
    33. user.setUserId(bladeUserV2DO.getId());
    34. user.setDeptId(0L);
    35. if(StringUtils.isNotEmpty(bladeUserV2DO.getDeptId())){
    36. user.setDeptId(Long.parseLong(bladeUserV2DO.getDeptId()));
    37. }
    38. user.setEmail(bladeUserV2DO.getEmail());
    39. user.setDelFlag("0");
    40. user.setNickName(bladeUserV2DO.getRealName());
    41. user.setUserName(bladeUserV2DO.getAccount());
    42. user.setPhonenumber(bladeUserV2DO.getPhone());
    43. user.setCreateTime(bladeUserV2DO.getCreateTime());
    44. user.setRoleId(0L);
    45. // 必须复制加密后的密码,后续框架一直在验证
    46. // 上面已经把123456对应的加密字符串保存进来,这里直接复制进去
    47. // 后续的框架一直在验证
    48. user.setPassword(bladeUserV2DO.getPassword());
    49. if(StringUtils.isNotEmpty(bladeUserV2DO.getRoleId())){
    50. user.setRoleId(Long.parseLong(bladeUserV2DO.getRoleId()));
    51. }
    52. user.setSex(bladeUserV2DO.getSex()+"");
    53. // LoginUser直接修改代码,把自己需要添加的字段都写进去,生成对应的set和get方法就行
    54. return new LoginUser(user.getUserId(), user.getDeptId(),
    55. user, permissionService.getMenuPermission(user),
    56. bladeUserRespVo.getIsSuperAdmin(),bladeUserRespVo.getIsAdmin()
    57. ,bladeUserV2DO.getAccount());
    58. }
    59. public LoginUser(Long userId, Long deptId, SysUser user, Set permissions,int isSuperAdmin,int isAdmin, String account)
    60. {
    61. this.userId = userId;
    62. this.deptId = deptId;
    63. this.user = user;
    64. this.permissions = permissions;
    65. //增加自己的字段
    66. this.isSuperAdmin = isSuperAdmin;
    67. this.isAdmin = isAdmin;
    68. this.account = account;
    69. }

    4、SysPasswordService.java

    这里的validate方法中,把没有用的逻辑注释掉。

    1. /**
    2. * 登录账户密码错误次数缓存键名
    3. *
    4. * @param username 用户名
    5. * @return 缓存键key
    6. */
    7. private String getCacheKey(String username)
    8. {
    9. return CacheConstants.PWD_ERR_CNT_KEY + username;
    10. }
    11. public void validate(BladeUserV2DO bladeUserV2DO)
    12. {
    13. Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
    14. String username = usernamePasswordAuthenticationToken.getName();
    15. String password = usernamePasswordAuthenticationToken.getCredentials().toString();
    16. // Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
    17. //
    18. // if (retryCount == null)
    19. // {
    20. // retryCount = 0;
    21. // }
    22. //
    23. // if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
    24. // {
    25. // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
    26. // MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
    27. // throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
    28. // }
    29. if (!matches(bladeUserV2DO, password))
    30. {
    31. // retryCount = retryCount + 1;
    32. // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
    33. // MessageUtils.message("user.password.retry.limit.count", retryCount)));
    34. // redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
    35. throw new UserPasswordNotMatchException();
    36. }
    37. else
    38. {
    39. clearLoginRecordCache(username);
    40. }
    41. }

    5、PasswordUtil.java

    如果你用的md5加密就不需要我的这个工具类

    1. package com.ruoyi.common.utils;
    2. import jodd.util.StringUtil;
    3. import org.apache.commons.codec.Charsets;
    4. import org.springframework.lang.Nullable;
    5. import org.springframework.util.DigestUtils;
    6. import javax.crypto.Mac;
    7. import javax.crypto.spec.SecretKeySpec;
    8. import java.security.InvalidKeyException;
    9. import java.security.MessageDigest;
    10. import java.security.NoSuchAlgorithmException;
    11. public class PasswordUtil extends DigestUtils {
    12. private static final char[] HEX_CODE = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    13. public PasswordUtil() {
    14. }
    15. public static String md5Hex(final String data) {
    16. return DigestUtils.md5DigestAsHex(data.getBytes(Charsets.UTF_8));
    17. }
    18. public static String md5Hex(final byte[] bytes) {
    19. return DigestUtils.md5DigestAsHex(bytes);
    20. }
    21. public static String sha1Hex(String data) {
    22. return sha1Hex(data.getBytes(Charsets.UTF_8));
    23. }
    24. public static String sha1Hex(final byte[] bytes) {
    25. return digestHex("SHA-1", bytes);
    26. }
    27. public static String sha224Hex(String data) {
    28. return sha224Hex(data.getBytes(Charsets.UTF_8));
    29. }
    30. public static String sha224Hex(final byte[] bytes) {
    31. return digestHex("SHA-224", bytes);
    32. }
    33. public static String sha256Hex(String data) {
    34. return sha256Hex(data.getBytes(Charsets.UTF_8));
    35. }
    36. public static String sha256Hex(final byte[] bytes) {
    37. return digestHex("SHA-256", bytes);
    38. }
    39. public static String sha384Hex(String data) {
    40. return sha384Hex(data.getBytes(Charsets.UTF_8));
    41. }
    42. public static String sha384Hex(final byte[] bytes) {
    43. return digestHex("SHA-384", bytes);
    44. }
    45. public static String sha512Hex(String data) {
    46. return sha512Hex(data.getBytes(Charsets.UTF_8));
    47. }
    48. public static String sha512Hex(final byte[] bytes) {
    49. return digestHex("SHA-512", bytes);
    50. }
    51. public static String digestHex(String algorithm, byte[] bytes) {
    52. try {
    53. MessageDigest md = MessageDigest.getInstance(algorithm);
    54. return encodeHex(md.digest(bytes));
    55. } catch (NoSuchAlgorithmException var3) {
    56. var3.printStackTrace();
    57. }
    58. return null;
    59. }
    60. public static String hmacMd5Hex(String data, String key) {
    61. return hmacMd5Hex(data.getBytes(Charsets.UTF_8), key);
    62. }
    63. public static String hmacMd5Hex(final byte[] bytes, String key) {
    64. return digestHMacHex("HmacMD5", bytes, key);
    65. }
    66. public static String hmacSha1Hex(String data, String key) {
    67. return hmacSha1Hex(data.getBytes(Charsets.UTF_8), key);
    68. }
    69. public static String hmacSha1Hex(final byte[] bytes, String key) {
    70. return digestHMacHex("HmacSHA1", bytes, key);
    71. }
    72. public static String hmacSha224Hex(String data, String key) {
    73. return hmacSha224Hex(data.getBytes(Charsets.UTF_8), key);
    74. }
    75. public static String hmacSha224Hex(final byte[] bytes, String key) {
    76. return digestHMacHex("HmacSHA224", bytes, key);
    77. }
    78. public static byte[] hmacSha256(String data, String key) {
    79. return hmacSha256(data.getBytes(Charsets.UTF_8), key);
    80. }
    81. public static byte[] hmacSha256(final byte[] bytes, String key) {
    82. return digestHMac("HmacSHA256", bytes, key);
    83. }
    84. public static String hmacSha256Hex(String data, String key) {
    85. return hmacSha256Hex(data.getBytes(Charsets.UTF_8), key);
    86. }
    87. public static String hmacSha256Hex(final byte[] bytes, String key) {
    88. return digestHMacHex("HmacSHA256", bytes, key);
    89. }
    90. public static String hmacSha384Hex(String data, String key) {
    91. return hmacSha384Hex(data.getBytes(Charsets.UTF_8), key);
    92. }
    93. public static String hmacSha384Hex(final byte[] bytes, String key) {
    94. return digestHMacHex("HmacSHA384", bytes, key);
    95. }
    96. public static String hmacSha512Hex(String data, String key) {
    97. return hmacSha512Hex(data.getBytes(Charsets.UTF_8), key);
    98. }
    99. public static String hmacSha512Hex(final byte[] bytes, String key) {
    100. return digestHMacHex("HmacSHA512", bytes, key);
    101. }
    102. public static String digestHMacHex(String algorithm, final byte[] bytes, String key) {
    103. SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
    104. try {
    105. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
    106. mac.init(secretKey);
    107. return encodeHex(mac.doFinal(bytes));
    108. } catch (InvalidKeyException | NoSuchAlgorithmException var5) {
    109. var5.printStackTrace();
    110. }
    111. return null;
    112. }
    113. public static byte[] digestHMac(String algorithm, final byte[] bytes, String key) {
    114. SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);
    115. try {
    116. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
    117. mac.init(secretKey);
    118. return mac.doFinal(bytes);
    119. } catch (InvalidKeyException | NoSuchAlgorithmException var5) {
    120. var5.printStackTrace();
    121. }
    122. return null;
    123. }
    124. public static String encodeHex(byte[] bytes) {
    125. StringBuilder r = new StringBuilder(bytes.length * 2);
    126. byte[] var2 = bytes;
    127. int var3 = bytes.length;
    128. for(int var4 = 0; var4 < var3; ++var4) {
    129. byte b = var2[var4];
    130. r.append(HEX_CODE[b >> 4 & 15]);
    131. r.append(HEX_CODE[b & 15]);
    132. }
    133. return r.toString();
    134. }
    135. public static boolean slowEquals(@Nullable String a, @Nullable String b) {
    136. return a != null && b != null ? slowEquals(a.getBytes(Charsets.UTF_8), b.getBytes(Charsets.UTF_8)) : false;
    137. }
    138. public static boolean slowEquals(@Nullable byte[] a, @Nullable byte[] b) {
    139. if (a != null && b != null) {
    140. if (a.length != b.length) {
    141. return false;
    142. } else {
    143. int diff = a.length ^ b.length;
    144. for(int i = 0; i < a.length; ++i) {
    145. diff |= a[i] ^ b[i];
    146. }
    147. return diff == 0;
    148. }
    149. } else {
    150. return false;
    151. }
    152. }
    153. public static String hex(String data) {
    154. return StringUtil.isBlank(data) ? "" : sha1Hex(data);
    155. }
    156. public static String encrypt(String data) {
    157. return StringUtil.isBlank(data) ? "" : sha1Hex(md5Hex(data));
    158. }
    159. }

    6、完结

  • 相关阅读:
    C++简单实现多态案例-制作饮品
    1526_AURIX TC275 BootROM下
    什么是hive的静态分区和动态分区,hive动态分区详解
    GDScript进行HTTP请求以及session问题
    Java的IO流-数据流
    UNI-APP_iphone苹果手机底部安全区域
    process.env.NODE_ENV
    哈工大机器人竞技队成立22年来4次获国际冠军
    【Spring】——8、如何使用FactoryBean向Spring容器中注册bean?
    腾讯云产品可观测最佳实践 (Function)¶
  • 原文地址:https://blog.csdn.net/renkai721/article/details/133166592