旧系统迁移到 RuoYi 的账号系统

文章目录

    RuoYi 账号表中的密码字段是否可以更改加密方案

    参考下面的配置文件

    framework\config\SecurityConfig.java

    只要实现一个自定义的 PasswordEncoder 接口,就可以在 RuoYi 框架中使用不同的加密方案。

    /**
    * 身份验证实现
    */
    @Bean
    public AuthenticationManager authenticationManager()
    {
    	DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    	daoAuthenticationProvider.setUserDetailsService(userDetailsService);
    	daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());   // 注入自定义加密器
    	return new ProviderManager(daoAuthenticationProvider);
    }
    
    /**
    * 强散列哈希加密实现
    */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder()
    {
    	return new BCryptPasswordEncoder();
    }
    

    替换之后,需要注意将原来的 admin 账号的密码也要重新加密,否则无法登录。

    Oracle 触发器是否能实现全量同步

    触发器本身不支持对已有数据进行全量同步。触发器的设计初衷是响应DML事件(INSERT、UPDATE、DELETE),只处理当前操作的新增或修改行,不会触碰已经存在的历史数据。

    • 先做全量同步
    • 再创建增量同步触发器

    通过判断两张表的数据总量来判断是否一致。

    Oracle 触发器中是否可以实现 MD5 Hash 的加密算法

    使用 DBMS_CRYPTO

    CREATE OR REPLACE FUNCTION ACCOUNT_PWD_MD5(p_str IN VARCHAR2)
    RETURN VARCHAR2
    IS
    BEGIN
       -- DBMS_CRYPTO.HASH 返回RAW类型,用LOWER转为小写
       RETURN LOWER(RAWTOHEX(DBMS_CRYPTO.HASH(UTL_I18N.STRING_TO_RAW(p_str, 'AL32UTF8'), DBMS_CRYPTO.HASH_MD5)));
    END ACCOUNT_PWD_MD5;
    /
    

    其实用不到这个功能,因为原来的用户表中已经有了 MD5 的密码字段 PASSWD,直接使用这个字段就可以了。
    不需要自己在数据库触发器里再去计算 MD5 了。

    改密码问题

    修改 RuoYi 的修改密码逻辑,修改密码时,直接修改旧系统账号表的密码和密码修改时间字段,依赖旧账号表的触发器来同步到 RuoYi 的账号表中。

    其他的账号信息的修改,例如账号禁用,之类的操作,也可以通过修改旧系统账号表来实现,依赖触发器来同步到 RuoYi 的账号表中。

    旧表插入数据错误

    TRG_SYSUSER_SYNC 已编译 (出现错误)
    
    任务已取消:
    INSERT INTO xxx
    ORA-04098: 触发器 'xxx.TRG_SYSUSER_SYNC' 无效且未通过重新验证
    ORA-06512: 在 line 1
    
    https://docs.oracle.com/error-help/db/ora-04098/
    
    保存对表 "xxx"."SYSUSER" 的更改时出现一个错误:
    行 1: ORA-04098: 触发器 'xxx.TRG_SYSUSER_SYNC' 无效且未通过重新验证
    ORA-06512: 在 line 1
    
    https://docs.oracle.com/error-help/db/ora-04098/
    

    排查方法:

    -- 查看当前用户下所有无效对象的编译错误
    SELECT * FROM USER_ERRORS WHERE NAME = 'TRG_SYSUSER_SYNC';
    

    显示错误:

    TRG_SYSUSER_SYNC	TRIGGER	1	67	17	PL/SQL: ORA-02289: 序列不存在	ERROR	0
    TRG_SYSUSER_SYNC	TRIGGER	2	6	9	PL/SQL: SQL Statement ignored	ERROR	0
    

    估计是因为在新表插入记录时,把 user_id 字段设置为 seq_sys_user.NEXTVAL, 但是 seq_sys_user 序列还没有创建,导致触发器编译失败。

    什么是 Oracle 的序列呢?难道 Oracle 没有自增索引?

    序列(SEQUENCE) 是Oracle中一个独立的数据库对象,专门用来生成一系列唯一的数字。它就像一个“数字发号器”,不依附于任何特定的表。

    你可以把它想象成一个全局计数器:

    • 调用 序列名.NEXTVAL 会获取下一个数字并自动递增。
    • 调用 序列名.CURRVAL 会获取当前会话最后一次获取的数字。

    从 Oracle 12c 开始,Oracle终于原生支持了类似MySQL的 AUTO_INCREMENT 语法,叫做 IDENTITY 列。
    之前则需要使用序列和触发器来模拟自增主键的行为。

    如何创建 Oracle 序列呢?

    CREATE SEQUENCE seq_sys_user
      START WITH 1
      INCREMENT BY 1
      NOCACHE
      NOCYCLE;
    

    如何查看一个指定序列是否存在?

    SELECT * FROM USER_SEQUENCES WHERE SEQUENCE_NAME = 'SEQ_SYS_USER';
    

    果然,测试环境中没有这个序列,而生产环境却有这个序列。

    创建完成后,再次插入 sysuser 表的记录,触发器就可以正常工作了。

    有一点不完美的地方是,如果新表中已经有了一条记录,那么这个序列的起始值就不能从 1 开始了,否则会出现主键冲突的错误。
    需要设置为 start with 当前表中最大 user_id 的值加 1。

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式