Oracle APEX中如何将加密密码存入DJELATNIK表?
自定义Oracle认证方案及密码存储问题解决思路
一、现有认证函数实现
1. 用户认证函数 prijava_custom
用户数据存储在DJELATNIK表,包含KORISNICKO_IME(用户名)、LOZINKA(密码)字段,该函数在用户名匹配且加密后密码一致时返回true:
create or replace FUNCTION prijava_custom(p_username IN VARCHAR2, p_password IN VARCHAR2) RETURN BOOLEAN AS v_korisnicko varchar2(100); v_lozinka varchar2(100); BEGIN SELECT KORISNICKO_IME, LOZINKA INTO v_korisnicko, v_lozinka FROM DJELATNIK WHERE UPPER(KORISNICKO_IME) = UPPER(p_username) AND LOZINKA = enkripcija_MD5(p_password); RETURN TRUE; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN FALSE; END;
2. MD5加密函数 enkripcija_MD5
用于对密码进行MD5加密,供认证函数调用:
create or replace Function enkripcija_MD5 (pstring IN VARCHAR2) Return VARCHAR2 IS hash_lozinka VARCHAR2(32) := '' ; BEGIN hash_lozinka := DBMS_OBFUSCATION_TOOLKIT.md5(input => UTL_I18N.STRING_TO_RAW (pstring, 'AL32UTF8' )); RETURN hash_lozinka; END enkripcija_MD5;
二、当前问题及解决思路
尝试通过表单编辑页面的「After submit」流程、动态动作设置哈希值,均无法将加密后的密码存入DJELATNIK表,以下是可行的解决思路:
1. 前端提交前替换密码值(动态动作)
给密码输入项创建Before Submit类型的动态动作:
- 触发条件设为「提交按钮被点击」
- 动作选择「设置值」,目标为密码页面项
- 值类型选「PL/SQL表达式」,输入:
enkripcija_MD5(:PXX_LOZINKA)(替换PXX_LOZINKA为实际页面项名称) - 注意:必须用
Before Submit,After Submit时机太晚,表单已提交明文值。
2. 数据库层兜底(触发器)
创建BEFORE INSERT OR UPDATE触发器,自动加密密码,无需依赖前端操作:
CREATE OR REPLACE TRIGGER trg_djelatnik_encrypt_password BEFORE INSERT OR UPDATE OF LOZINKA ON DJELATNIK FOR EACH ROW BEGIN -- 避免重复加密,仅当密码长度不等于32位(MD5哈希长度)时执行加密 IF LENGTH(:NEW.LOZINKA) != 32 THEN :NEW.LOZINKA := enkripcija_MD5(:NEW.LOZINKA); END IF; END; /
3. 表单流程前置处理(Process)
在Oracle APEX表单中创建Before Processing类型的流程,优先级高于默认DML流程:
- 流程类型选「PL/SQL代码」
- 代码内容:
:PXX_LOZINKA := enkripcija_MD5(:PXX_LOZINKA)(替换为实际页面项名称) - 该流程会在表单执行插入/更新前,将明文密码替换为加密后的值。
内容的提问来源于stack exchange,提问作者Fiki
相关产品推荐
相关产品推荐

