【问题标题】:Oracle Apex cookie expiration offset by 8 hoursOracle Apex cookie 过期偏移 8 小时
【发布时间】:2021-11-01 09:24:59
【问题描述】:

我使用 owa_cookie.send 创建的 cookie 的到期日期还有 8 小时。

服务器使用 UTC 时间(select to_char(sysdate, 'hh24:mi') from dual 的结果与当前 UTC 时间相同)。所以我认为差异不是时区造成的。

我现在使用以下调用来创建 cookie(注意 expires 上的 -8/24)。它现在可以工作,但这似乎不是很安全。

-- 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 - 8) / 24,
  path => '/ords',
  secure => 'Y',
  httponly => null);

有人知道时差是从哪里来的吗?

【问题讨论】:

    标签: oracle cookies timezone oracle-apex


    【解决方案1】:

    你有一个从 TIMESTAMPTIMESTAMP WITH TIME ZONE 的隐式转换:

    to_char(
      cast((sysdate + 1/24) as timestamp) -- TIMESTAMP (without time zone)
      at time zone 'UTC',                 -- TIMESTAMP WITH TIME ZONE
      'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'
    )
    

    这实际上是在添加一个时区:

    to_char(
      cast(sysdate + 1/24 as timestamp with local time zone)
      at time zone 'UTC',
      'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'
    )
    

    它将数据库时区中的SYSDATE 转换为本地时区(无论客户端应用程序使用哪个时区,而不是数据库时区),然后将其转换为UTC。


    您最好使用SYSTIMESTAMP 而不是SYSDATE,这样可以避免很多关于数据类型和时区的困惑:

    TO_CHAR(
      (SYSTIMESTAMP + INTERVAL '1' HOUR) AT TIME ZONE 'UTC',
      'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"'
    )
    

    但是,如果您确实想使用SYSDATE,请使用数据库时区而不是本地(客户端)时区:

    to_char(
      FROM_TZ(CAST(sysdate + 1/24 AS TIMESTAMP), DBTIMEZONE)
      at time zone 'UTC',
      'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'
    )
    

    例如,如果数据库时间是 UTC 而你这样做:

    ALTER SESSION SET TIME_ZONE = 'Asia/Shanghai';
    
    SELECT 'SYSDATE with implicit local cast' AS method,
           to_char(
             cast(sysdate + 1/24 as timestamp)
             at time zone 'UTC',
             'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'
           ) AS utc_timestamp
    FROM   DUAL
    UNION ALL
    SELECT 'SYSDATE with explicit local cast',
           to_char(
             cast(sysdate + 1/24 as timestamp with local time zone)
             at time zone 'UTC',
             'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'
           )
    FROM   DUAL
    UNION ALL
    SELECT 'SYSDATE with explicit DB timezone cast',
           to_char(
             FROM_TZ(CAST(sysdate + 1/24 AS TIMESTAMP), DBTIMEZONE)
             at time zone 'UTC',
             'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"'
           )
    FROM   DUAL
    UNION ALL
    SELECT 'SYSTIMESTAMP',
           TO_CHAR(
             (SYSTIMESTAMP + INTERVAL '1' HOUR) AT TIME ZONE 'UTC',
             'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"'
           )
    FROM   DUAL;
    

    那么输出是:

    METHOD UTC_TIMESTAMP
    SYSDATE with implicit local cast 2021-11-01T04:07:04.000Z
    SYSDATE with explicit local cast 2021-11-01T04:07:04.000Z
    SYSDATE with explicit DB timezone cast 2021-11-01T12:07:04.000Z
    SYSTIMESTAMP 2021-11-01T12:07:04.200Z

    db小提琴here

    【讨论】:

    • 感谢您的回复,我更改了valueexpires参数,使它们使用SYSTIMESTAMP + INTERVAL '1' HOUR而不是sysdate + 1/24,cookie的值仍然不错但是过期了8 小时后仍然关闭。
    • @nickzoum OWA_COOKIE.SEND 上的文档不清楚它的预期(以及它是否会假设任何时区并将任何转换应用到 UTC),但您也可以尝试传递 expires => (SYSTIMESTAMP + INTERVAL '1' HOUR) AT TIME ZONE 'UTC',,它会隐式转换回预期的 DATE 数据类型。
    • 我已经尝试过了,它仍然关闭了 8。我请求了一个演示 apex 工作区,以便可以轻松地重现该问题。 URL:https://apex.oracle.com/pls/apex/,工作空间:nzapptest,用户名和密码:testtest。该请求位于 SQL Workshop>RESTful Services>modules>test>expiration>get
    • @nickzoum 我尝试了一些位,但无法达到您想要的值;但是,您对“服务器正在使用 UTC 时间”的假设是不正确的,因为 DBTIMEZONE-05:00(但这仍然不是 8 小时的差异)。
    • 查询select DBTIMEZONE from dual 在我正在处理的服务器上返回+00:00(它是我请求的测试服务器上的-05:00,以便在不共享敏感数据的情况下轻松重现问题)。这是否意味着问题很可能与时区无关,而是由 owa_cookie 包或 apex 添加的固定 +8 小时?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    相关资源
    最近更新 更多