如何禁止用户在Oracle APEX应用中打开多个标签页与独立窗口
Oracle APEX 20.2 禁止多标签/多窗口打开应用实现方案
以下方案均适配ORDS部署的APEX 20.2版本,可根据业务安全要求组合使用:
方案1:服务端绑定标签标识校验(安全等级最高)
核心逻辑是将APEX会话和唯一的标签页标识绑定,前后端双重校验,可完全避免前端篡改绕过:
- 登录成功后生成随机唯一的标签页标识,分别存到两处:
- 前端当前窗口的
sessionStorage(单标签隔离,不同标签/窗口无法读取) - 服务端通过
APEX_UTIL.SET_SESSION_STATE存储到当前APEX会话的自定义属性,或写入自行维护的会话关联表
- 前端当前窗口的
- 在应用全局页(页0)新增页面加载动态动作,每次页面加载时执行以下逻辑:
- 读取当前
sessionStorage内的标签标识,为空则直接触发登出逻辑 - 调用APEX按需执行进程或ORDS自定义REST接口,将前端标识传给服务端和当前会话绑定的标识做比对,比对失败则返回会话失效信号,前端弹出提示并执行登出
- 读取当前
方案2:Broadcast Channel 前端实时拦截(实现成本最低)
仅通过前端API即可实现实时拦截,适合安全要求中等的内部应用:
- 在全局页(页0)的页面加载事件中初始化
BroadcastChannel实例,通道名设置为应用唯一标识,比如XX_APP_SINGLE_INSTANCE - 新标签页打开应用时,先通过通道广播
check_instance消息 - 已存活的应用窗口收到消息后,返回
instance_exist响应 - 新窗口收到响应后直接跳转至提示页,提示“请勿多开应用”,或自动关闭当前窗口
- 额外绑定
beforeunload事件,窗口正常关闭时广播退出信号,避免正常关闭后新窗口无法打开的问题
方案3:会话Cookie时间戳轮询校验(兼容性最好)
适配不支持Broadcast Channel的旧浏览器场景:
- 前端设置10秒固定轮询,每次将当前时间戳写入仅当前域名生效的非持久会话Cookie,同时将时间戳存到当前窗口的
sessionStorage - 每次页面加载时对比Cookie内的时间戳和
sessionStorage存储的上一次时间戳,差值大于15秒则说明是新标签页读取了其他窗口更新的Cookie,直接触发拦截逻辑 - 服务端可同步校验Cookie时间戳和会话存储的上一次有效时间,不一致则直接销毁当前APEX会话
注意事项
- 所有方案建议搭配APEX自带的会话超时配置使用,可设置5-10分钟无操作超时,避免用户异常关闭窗口后无法重新登录的问题
- 若需要支持用户主动踢出旧窗口登录,可在校验不通过时增加“强制登录”选项,用户确认后更新服务端绑定的标签标识,旧窗口后续校验时会自动登出
- 核心校验逻辑必须放在服务端执行,前端JS建议做混淆处理,避免用户通过控制台篡改绕过校验
内容的提问来源于stack exchange,提问作者ali yousef
相关产品推荐
相关产品推荐

