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

背景

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

修改教程

1、SysLoginController.java

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

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

2、SysLoginService.java

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

/**
     * 登录验证
     * 
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    public Map<String, Object> login(String username, String password, String code, String uuid)
    {
        // 验证码校验
        validateCaptcha(username, code, uuid);
        // 登录前置校验
        loginPreCheck(username, password);
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        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());
            }
        }
        finally
        {
            AuthenticationContextHolder.clearContext();
        }
        //AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        //recordLoginInfo(loginUser.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("token",tokenService.createToken(loginUser));
        map.put("loginUser",loginUser);
        // 生成token
        return map;
    }

/**
     * 登录前置校验
     * @param username 用户名
     * @param password 用户密码
     */
    public void loginPreCheck(String username, String password)
    {
        // 用户名或密码为空 错误
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
            throw new UserNotExistsException();
        }
        // 密码如果不在指定范围内 错误
//        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
//                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
//            throw new UserPasswordNotMatchException();
//        }
//        // 用户名不在指定范围内 错误
//        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
//                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
//            throw new UserPasswordNotMatchException();
//        }
//        // IP黑名单校验
//        String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
//        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
//            throw new BlackListException();
//        }
    }

3、loadUserByUsername方法

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

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
// 这是自己的页面输入的密码,没有加密,比如123456
        String inputPassword = usernamePasswordAuthenticationToken.getCredentials().toString();
        // 这里是自定义的表查询,用户和密码验证,如果还有其他的验证都可以在这里进行添加
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<BladeUserV2DO>()
                .eq(BladeUserV2DO::getAccount,username)
                //PasswordUtil是自己的加密工具,你用什么加密就保持原来的就行
                .eq(BladeUserV2DO::getPassword, PasswordUtil.encrypt(inputPassword))
                .eq(BladeUserV2DO::getIsDeleted,0);
        // 这里写自己的登录验证逻辑
        BladeUserV2DO bladeUserV2DO = bladeUserV2Mapper.selectOne(wrapper);
//        SysUser user = userService.selectUserByUserName(username);
        if (StringUtils.isNull(bladeUserV2DO))
        {
            log.info("登录用户:{} 不存在.", username);
            throw new UserPasswordNotMatchException();
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // 这里一定要把加密后的密码放进去,后面的验证中会一直用这个密码
        // 这个是123456加密后的密码,这里给框架都是完全通过的密码,
        // 因为我们在方法开始的时候自己进行密码验证,能走到这里都是验证通过的
        bladeUserV2DO.setPassword(passwordEncoder.encode(inputPassword));
        passwordService.validate(bladeUserV2DO);
        return createLoginUser(bladeUserV2DO);
    }

    public UserDetails createLoginUser(BladeUserV2DO bladeUserV2DO)
    {
        BladeUserRespVo bladeUserRespVo = bladeUserV2Mapper.getBladeUserInfo(bladeUserV2DO.getId());
        SysUser user = new SysUser();
        user.setUserId(bladeUserV2DO.getId());
        user.setDeptId(0L);
        if(StringUtils.isNotEmpty(bladeUserV2DO.getDeptId())){
            user.setDeptId(Long.parseLong(bladeUserV2DO.getDeptId()));
        }
        user.setEmail(bladeUserV2DO.getEmail());
        user.setDelFlag("0");
        user.setNickName(bladeUserV2DO.getRealName());
        user.setUserName(bladeUserV2DO.getAccount());
        user.setPhonenumber(bladeUserV2DO.getPhone());
        user.setCreateTime(bladeUserV2DO.getCreateTime());
        user.setRoleId(0L);
        // 必须复制加密后的密码,后续框架一直在验证
        // 上面已经把123456对应的加密字符串保存进来,这里直接复制进去
        // 后续的框架一直在验证
        user.setPassword(bladeUserV2DO.getPassword());
        if(StringUtils.isNotEmpty(bladeUserV2DO.getRoleId())){
            user.setRoleId(Long.parseLong(bladeUserV2DO.getRoleId()));
        }
        user.setSex(bladeUserV2DO.getSex()+"");
        // LoginUser直接修改代码,把自己需要添加的字段都写进去,生成对应的set和get方法就行
        return new LoginUser(user.getUserId(), user.getDeptId(),
                user, permissionService.getMenuPermission(user),
                bladeUserRespVo.getIsSuperAdmin(),bladeUserRespVo.getIsAdmin()
                ,bladeUserV2DO.getAccount());
    }


public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions,int isSuperAdmin,int isAdmin, String account)
    {
        this.userId = userId;
        this.deptId = deptId;
        this.user = user;
        this.permissions = permissions;
        //增加自己的字段
        this.isSuperAdmin = isSuperAdmin;
        this.isAdmin = isAdmin;
        this.account = account;
    }

4、SysPasswordService.java

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

/**
     * 登录账户密码错误次数缓存键名
     * 
     * @param username 用户名
     * @return 缓存键key
     */
    private String getCacheKey(String username)
    {
        return CacheConstants.PWD_ERR_CNT_KEY + username;
    }

    public void validate(BladeUserV2DO bladeUserV2DO)
    {
        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
        String username = usernamePasswordAuthenticationToken.getName();
        String password = usernamePasswordAuthenticationToken.getCredentials().toString();
//        Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
//
//        if (retryCount == null)
//        {
//            retryCount = 0;
//        }
//
//        if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
//                    MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
//            throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
//        }
        if (!matches(bladeUserV2DO, password))
        {
//            retryCount = retryCount + 1;
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
//                    MessageUtils.message("user.password.retry.limit.count", retryCount)));
//            redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
            throw new UserPasswordNotMatchException();
        }
        else
        {
            clearLoginRecordCache(username);
        }
    }

5、PasswordUtil.java

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

package com.ruoyi.common.utils;

import jodd.util.StringUtil;
import org.apache.commons.codec.Charsets;
import org.springframework.lang.Nullable;
import org.springframework.util.DigestUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class PasswordUtil extends DigestUtils {
    private static final char[] HEX_CODE = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public PasswordUtil() {
    }

    public static String md5Hex(final String data) {
        return DigestUtils.md5DigestAsHex(data.getBytes(Charsets.UTF_8));
    }

    public static String md5Hex(final byte[] bytes) {
        return DigestUtils.md5DigestAsHex(bytes);
    }

    public static String sha1Hex(String data) {
        return sha1Hex(data.getBytes(Charsets.UTF_8));
    }

    public static String sha1Hex(final byte[] bytes) {
        return digestHex("SHA-1", bytes);
    }

    public static String sha224Hex(String data) {
        return sha224Hex(data.getBytes(Charsets.UTF_8));
    }

    public static String sha224Hex(final byte[] bytes) {
        return digestHex("SHA-224", bytes);
    }

    public static String sha256Hex(String data) {
        return sha256Hex(data.getBytes(Charsets.UTF_8));
    }

    public static String sha256Hex(final byte[] bytes) {
        return digestHex("SHA-256", bytes);
    }

    public static String sha384Hex(String data) {
        return sha384Hex(data.getBytes(Charsets.UTF_8));
    }

    public static String sha384Hex(final byte[] bytes) {
        return digestHex("SHA-384", bytes);
    }

    public static String sha512Hex(String data) {
        return sha512Hex(data.getBytes(Charsets.UTF_8));
    }

    public static String sha512Hex(final byte[] bytes) {
        return digestHex("SHA-512", bytes);
    }

    public static String digestHex(String algorithm, byte[] bytes) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            return encodeHex(md.digest(bytes));
        } catch (NoSuchAlgorithmException var3) {
            var3.printStackTrace();
        }
        return null;
    }

    public static String hmacMd5Hex(String data, String key) {
        return hmacMd5Hex(data.getBytes(Charsets.UTF_8), key);
    }

    public static String hmacMd5Hex(final byte[] bytes, String key) {
        return digestHMacHex("HmacMD5", bytes, key);
    }

    public static String hmacSha1Hex(String data, String key) {
        return hmacSha1Hex(data.getBytes(Charsets.UTF_8), key);
    }

    public static String hmacSha1Hex(final byte[] bytes, String key) {
        return digestHMacHex("HmacSHA1", bytes, key);
    }

    public static String hmacSha224Hex(String data, String key) {
        return hmacSha224Hex(data.getBytes(Charsets.UTF_8), key);
    }

    public static String hmacSha224Hex(final byte[] bytes, String key) {
        return digestHMacHex("HmacSHA224", bytes, key);
    }

    public static byte[] hmacSha256(String data, String key) {
        return hmacSha256(data.getBytes(Charsets.UTF_8), key);
    }

    public static byte[] hmacSha256(final byte[] bytes, String key) {
        return digestHMac("HmacSHA256", bytes, key);
    }

    public static String hmacSha256Hex(String data, String key) {
        return hmacSha256Hex(data.getBytes(Charsets.UTF_8), key);
    }

    public static String hmacSha256Hex(final byte[] bytes, String key) {
        return digestHMacHex("HmacSHA256", bytes, key);
    }

    public static String hmacSha384Hex(String data, String key) {
        return hmacSha384Hex(data.getBytes(Charsets.UTF_8), key);
    }

    public static String hmacSha384Hex(final byte[] bytes, String key) {
        return digestHMacHex("HmacSHA384", bytes, key);
    }

    public static String hmacSha512Hex(String data, String key) {
        return hmacSha512Hex(data.getBytes(Charsets.UTF_8), key);
    }

    public static String hmacSha512Hex(final byte[] bytes, String key) {
        return digestHMacHex("HmacSHA512", bytes, key);
    }

    public static String digestHMacHex(String algorithm, final byte[] bytes, String key) {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);

        try {
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            return encodeHex(mac.doFinal(bytes));
        } catch (InvalidKeyException | NoSuchAlgorithmException var5) {
            var5.printStackTrace();
        }
        return null;
    }

    public static byte[] digestHMac(String algorithm, final byte[] bytes, String key) {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(Charsets.UTF_8), algorithm);

        try {
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            return mac.doFinal(bytes);
        } catch (InvalidKeyException | NoSuchAlgorithmException var5) {
            var5.printStackTrace();
        }
        return null;
    }

    public static String encodeHex(byte[] bytes) {
        StringBuilder r = new StringBuilder(bytes.length * 2);
        byte[] var2 = bytes;
        int var3 = bytes.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            byte b = var2[var4];
            r.append(HEX_CODE[b >> 4 & 15]);
            r.append(HEX_CODE[b & 15]);
        }

        return r.toString();
    }

    public static boolean slowEquals(@Nullable String a, @Nullable String b) {
        return a != null && b != null ? slowEquals(a.getBytes(Charsets.UTF_8), b.getBytes(Charsets.UTF_8)) : false;
    }

    public static boolean slowEquals(@Nullable byte[] a, @Nullable byte[] b) {
        if (a != null && b != null) {
            if (a.length != b.length) {
                return false;
            } else {
                int diff = a.length ^ b.length;

                for(int i = 0; i < a.length; ++i) {
                    diff |= a[i] ^ b[i];
                }

                return diff == 0;
            }
        } else {
            return false;
        }
    }

    public static String hex(String data) {
        return StringUtil.isBlank(data) ? "" : sha1Hex(data);
    }

    public static String encrypt(String data) {
        return StringUtil.isBlank(data) ? "" : sha1Hex(md5Hex(data));
    }
}

6、完结

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可能的原因是,在使用Ruoyi框架的分页功能时,它使用了Mybatis-Plus分页插件,而该插件在PostgreSQL数据库中不支持pageSize参数。 为了解决这个问题,可以尝试使用Mybatis-Plus提供的另一种分页方式——基于游标的分页(cursor-based pagination)。这种分页方式不需要使用pageSize参数,而是使用一个游标来实现分页功能。 具体实现方法可以参考Mybatis-Plus的官方文档或者相关的教程。需要注意的是,基于游标的分页方式可能会对数据库的性能产生一定的影响,因此需要根据具体的情况进行权衡和优化。 ### 回答2: 在Ruoyi框架中,使用pg(PostgreSQL)数据源时,不能直接使用pageSize实现分页的原因如下: 1. 数据库差异性:pg数据库与MySQL等数据库有所不同,其语法、查询方式以及对分页的支持方式也有所差异。 2. 语法差异:在pg数据库中,分页的语法使用的是"LIMIT"和"OFFSET",而不是常见的"LIMIT"和"OFFSET"的组合。 3. 查询效率:使用pageSize进行分页需要从查询结果集中选择指定数量的数据,而pg数据库在处理大量数据时可能会存在性能问题。 4. 兼容性:Ruoyi框架为了适配不同类型的数据库,采用了统一的分页方式,以提供更好的兼容性和易用性。 因此,在Ruoyi框架使用pg数据源时,需要使用Ruoyi框架提供的分页方式来实现分页功能。可以通过使用PageHelper插件或对Mapper接口方法进行自定义分页实现。这样可以确保在pg数据库下能够正确地实现分页功能,并提高查询效率。 总结而言,pg数据源下不能使用pageSize实现分页是因为pg数据库本身的语法和处理方式不同于其他数据库,需要使用Ruoyi框架提供的专门适配pg数据库的分页方式来实现分页功能。 ### 回答3: Ruoyi框架是一款基于Spring Boot开发的后台管理系统快速开发框架。在使用Ruoyi框架的分页实现中,对于pg数据源(即PostgreSQL数据库)来说,不能直接使用pageSize的原因是因为pg数据库中的分页语法与其他数据库(如MySQL)有所不同。 在大多数关系型数据库中,如MySQL,我们可以使用LIMIT关键字来实现分页查询,其中传入的两个参数分别示返回结果的偏移量和数量。而在pg数据库中,分页查询的语法是使用LIMIT和OFFSET两个关键字,其中LIMIT示返回的结果数量,而OFFSET示查询的偏移量。 所以,在Ruoyi框架的分页实现中,针对pg数据源,使用LIMIT关键字来指定数量是可以的,但是无法直接使用pageSize参数来指定。相反,我们需要根据pageSize和pageNum(当前页码)来计算出对应的偏移量,并将其作为OFFSET参数传入SQL查询语句中,以实现分页查询。 以Ruoyi框架中的分页工具PageHelper为例,当使用pg数据源时,我们需要通过计算pageSize和pageNum得出对应的偏移量,然后手动调用PageHelper.offsetPage方法指定偏移量和LIMIT参数即可实现分页查询。 综上所述,Ruoyi框架的分页实现在pg数据源下不能直接使用pageSize参数,是因为pg数据库的分页语法与其他数据库不同,需要使用LIMIT和OFFSET关键字来实现分页查询。我们可以通过计算偏移量并手动设置OFFSET参数来实现分页查询。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

renkai721

谢谢您的打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值