You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用XSLT1.0/2.0的datetime验证Epoch时间及JWT exp字段

没问题,我来帮你搞定这两个问题——用datetime验证JWT的exp(Epoch时间),以及用XSLT 1.0/2.0实现这个验证逻辑。

一、用Datetime验证Epoch时间的通用思路

首先明确:JWT里的exp是UTC时区下的Epoch时间戳(从1970-01-01T00:00:00Z开始的秒数),验证逻辑核心就是比较当前UTC时间的Epoch秒数和exp值的大小:如果当前时间戳 < exp,则令牌未过期,反之则过期。

关键注意点

  • 必须用UTC时间,不能用本地时间,否则会因为时区差导致验证错误。
  • 如果你还想验证TTL是否符合600秒的要求,可以计算exp - iat是否等于600(你的示例里1522945492 - 1522944892 = 600,正好符合)。

示例(以Python为例)

import datetime

# 从JWT解析出的exp值
exp_timestamp = 1522945492
# 获取当前UTC时间的Epoch秒数(必须用utc,避免时区问题)
current_timestamp = int(datetime.datetime.now(datetime.timezone.utc).timestamp())

# 验证过期时间
if current_timestamp < exp_timestamp:
    print("✅ 令牌未过期")
else:
    print("❌ 令牌已过期")

# 额外验证TTL是否为600秒
iat_timestamp = 1522944892
if exp_timestamp - iat_timestamp == 600:
    print("✅ TTL符合预期(600秒)")
else:
    print("❌ TTL不符合要求")

二、XSLT 1.0/2.0实现验证逻辑

XSLT 2.0和1.0的差异很大,2.0有原生的日期时间处理能力,1.0则需要手动实现或者依赖扩展,我分开来说:

1. XSLT 2.0 实现(推荐,更简洁)

XSLT 2.0支持xs:dateTime类型和时间运算,还能直接用json-to-xml()解析JWT的JSON字符串,步骤如下:

<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="/">
        <!-- 1. 定义JWT的JSON字符串(如果已经是XML结构可以跳过这一步) -->
        <xsl:variable name="jwt-json" select='"{ \"iss\": \"SOS\", \"sub\": \"SOS\", \"iat\": 1522944892, \"exp\": 1522945492, \"dfp\": \"123\" }"' />
        <!-- 2. 把JSON转成XML结构 -->
        <xsl:variable name="jwt-xml" select="json-to-xml($jwt-json)" />
        <!-- 3. 提取exp和iat字段 -->
        <xsl:variable name="exp" select="$jwt-xml//*[@key='exp']" />
        <xsl:variable name="iat" select="$jwt-xml//*[@key='iat']" />

        <!-- 4. 将exp转换为UTC日期时间 -->
        <xsl:variable name="exp-datetime" select="xs:dateTime('1970-01-01T00:00:00Z') + xs:dayTimeDuration(concat('PT', $exp, 'S'))" />
        <!-- 5. 获取当前UTC时间 -->
        <xsl:variable name="current-datetime" select="current-dateTime()" />

        <!-- 6. 验证过期时间 -->
        <xsl:choose>
            <xsl:when test="$current-datetime lt $exp-datetime">
                <validation-result>valid</validation-result>
                <message>令牌未过期</message>
            </xsl:when>
            <xsl:otherwise>
                <validation-result>invalid</validation-result>
                <message>令牌已过期</message>
            </xsl:otherwise>
        </xsl:choose>

        <!-- 额外验证TTL是否为600秒 -->
        <xsl:if test="$exp - $iat = 600">
            <ttl-check>pass</ttl-check>
            <ttl-message>TTL符合600秒要求</ttl-message>
        </xsl:if>
        <xsl:if test="$exp - $iat != 600">
            <ttl-check>fail</ttl-check>
            <ttl-message>TTL不符合要求,应为600秒</ttl-message>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

2. XSLT 1.0 实现(需手动处理日期)

XSLT 1.0没有原生的日期时间和Epoch转换函数,所以需要手动计算当前时间的Epoch秒数,或者依赖EXSLT扩展(如果你的处理器支持,比如Saxon、libxslt)。

方法:借助EXSLT获取当前时间 + 手动转换Epoch

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:date="http://exslt.org/dates-and-times"
                extension-element-prefixes="date">

    <xsl:template match="/">
        <!-- 1. 提取exp和iat(假设JWT已转为XML结构) -->
        <xsl:variable name="exp" select="/jwt/exp" />
        <xsl:variable name="iat" select="/jwt/iat" />

        <!-- 2. 获取当前UTC时间的ISO字符串(依赖EXSLT的date:date-time()) -->
        <xsl:variable name="current-iso" select="date:date-time()" />
        <!-- 3. 将ISO时间转换为Epoch秒数 -->
        <xsl:variable name="current-timestamp">
            <xsl:call-template name="iso-to-epoch">
                <xsl:with-param name="iso-date" select="$current-iso" />
            </xsl:call-template>
        </xsl:variable>

        <!-- 4. 验证过期时间 -->
        <xsl:choose>
            <xsl:when test="$current-timestamp &lt; $exp">
                <validation-result>valid</validation-result>
                <message>令牌未过期</message>
            </xsl:when>
            <xsl:otherwise>
                <validation-result>invalid</validation-result>
                <message>令牌已过期</message>
            </xsl:otherwise>
        </xsl:choose>

        <!-- 验证TTL -->
        <xsl:if test="$exp - $iat = 600">
            <ttl-check>pass</ttl-check>
        </xsl:if>
    </xsl:template>

    <!-- 自定义模板:将ISO 8601 UTC时间(如2024-05-20T12:34:56Z)转为Epoch秒数 -->
    <xsl:template name="iso-to-epoch">
        <xsl:param name="iso-date" />
        <!-- 拆分日期时间各部分 -->
        <xsl:variable name="year" select="substring($iso-date, 1, 4)" />
        <xsl:variable name="month" select="substring($iso-date, 6, 2)" />
        <xsl:variable name="day" select="substring($iso-date, 9, 2)" />
        <xsl:variable name="hour" select="substring($iso-date, 12, 2)" />
        <xsl:variable name="minute" select="substring($iso-date, 15, 2)" />
        <xsl:variable name="second" select="substring($iso-date, 18, 2)" />

        <!-- 计算1970到当前年份的总秒数(含闰年) -->
        <xsl:variable name="years-since-1970" select="$year - 1970" />
        <xsl:variable name="leap-years" select="floor(($year - 1968) div 4) - floor(($year - 1900) div 100) + floor(($year - 1600) div 400)" />
        <xsl:variable name="year-seconds" select="($years-since-1970 * 365 + $leap-years) * 86400" />

        <!-- 计算当年已过月份的总天数 -->
        <xsl:variable name="month-days">
            <xsl:choose>
                <xsl:when test="$month = 1">0</xsl:when>
                <xsl:when test="$month = 2">31</xsl:when>
                <xsl:when test="$month = 3">59</xsl:when>
                <xsl:when test="$month = 4">90</xsl:when>
                <xsl:when test="$month = 5">120</xsl:when>
                <xsl:when test="$month = 6">151</xsl:when>
                <xsl:when test="$month = 7">181</xsl:when>
                <xsl:when test="$month = 8">212</xsl:when>
                <xsl:when test="$month = 9">243</xsl:when>
                <xsl:when test="$month = 10">273</xsl:when>
                <xsl:when test="$month = 11">304</xsl:when>
                <xsl:when test="$month = 12">334</xsl:when>
            </xsl:choose>
        </xsl:variable>
        <!-- 闰年且月份>2时加1天 -->
        <xsl:variable name="leap-adjust" select="if ($year mod 4 = 0 and ($year mod 100 != 0 or $year mod 400 = 0) and $month > 2) then 1 else 0" />
        <xsl:variable name="month-seconds" select="($month-days + $leap-adjust) * 86400" />

        <!-- 计算当日、小时、分钟的秒数 -->
        <xsl:variable name="day-seconds" select="($day - 1) * 86400" />
        <xsl:variable name="hour-seconds" select="$hour * 3600" />
        <xsl:variable name="minute-seconds" select="$minute * 60" />

        <!-- 总Epoch秒数 -->
        <xsl:value-of select="$year-seconds + $month-seconds + $day-seconds + $hour-seconds + $minute-seconds + $second" />
    </xsl:template>

</xsl:stylesheet>

注意事项

  • 如果你的XSLT处理器不支持EXSLT,建议将当前Epoch时间作为参数传入样式表,这样可以避免手动计算的复杂和误差。
  • 手动计算闰年的逻辑覆盖了大部分场景,但对非常古老的年份可能存在误差,适合常规业务场景。

内容的提问来源于stack exchange,提问作者Kumar_y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:21:34