Oracle Apex使用owa_cookie.send创建Cookie过期时间多8小时问题咨询
这个8小时时间差的核心来源是:owa_cookie.send方法内部处理expires参数时,会默认将传入的DATE类型值按照Oracle数据库会话时区转换为HTTP协议要求的GMT格式过期时间,而你的数据库会话时区为东八区(UTC+8),和服务器操作系统使用UTC时间的配置相互独立,不受影响。
根因拆解
- 你验证的
sysdate返回值和UTC时间一致,只能说明服务器操作系统时区为UTC,sysdate取的是操作系统层面的时间,本身不受数据库时区参数控制。 - 实际转换逻辑可以用场景直观说明:
假设当前UTC时间为9:00,你设置1小时后过期,传入的expires值为sysdate + 1/24,也就是10:00(UTC时间值)。此时如果数据库会话时区为UTC+8,owa_cookie会默认把你传入的10:00当作东八区时间,转换为GMT时间时会加8小时,最终输出到Set-Cookie响应头的过期时间为18:00 GMT,和你预期的10:00 GMT刚好差了8小时,表现为Cookie实际过期时间比预设值多8小时。
验证方法
执行以下SQL查询当前会话时区即可确认:
SELECT SESSIONTIMEZONE FROM DUAL;
返回结果大概率为+08:00或Asia/Shanghai等东八区标识。
更稳妥的替代方案
避免硬编码8小时偏移,可以选择以下两种方案:
- 统一会话时区为UTC:在应用连接池(比如你用的ORDS)的初始化配置中,增加会话初始化语句
ALTER SESSION SET TIME_ZONE = 'UTC';,后续所有owa_cookie调用不需要修改代码即可按预期生效。 - 动态修正expires参数值:调用时自动扣除时区偏移,适配任意时区配置:
-- creates a cookie that lasts for 1 hour that can also be seen by JS -- the value of the cookie is the expiration date in ISO format owa_cookie.send( name => 'TEST_DTM', value => to_char(cast((sysdate + 1/24) as timestamp) at time zone 'UTC', 'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'), expires => sysdate + 1/24 - NUMTODSINTERVAL(EXTRACT(TIMEZONE_HOUR FROM SYSTIMESTAMP AT LOCAL), 'HOUR'), path => '/ords', secure => 'Y', httponly => null);
内容的提问来源于stack exchange,提问作者nick zoum
相关产品推荐
相关产品推荐

