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

使用firebase/php-jwt忽略JWT过期验证并获取Payload的方法

解决方案:忽略JWT过期验证并完成有效性校验

核心思路

firebase/php-jwt库的JWT::decode方法支持通过选项参数跳过过期时间校验,只需在调用时传入['ignore_expiration' => true]即可。同时仍需确保令牌的签名有效性、iss、uid等自定义字段的校验,避免安全风险。

修改后的完整代码

<?php

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\InvalidArgumentException;
require_once ("autoload.php");

function checkJWT($con,$userID,$jwt) {
    $domainName = "firebase-XXXXX-XXXXX@XXXXX-XXXXX-XXXXX.iam.gserviceaccount.com";
    $secret_Key  = "-----BEGIN PRIVATE KEY-----\XXXXXXX--XXXXX---END PRIVATE KEY-----\n";
    
    // 修复SQL注入风险:使用预处理语句
    $sql = "SELECT JWT,created FROM sample where id = ?";
    $stmt = mysqli_prepare($con, $sql);
    mysqli_stmt_bind_param($stmt, "i", $userID);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);
    $data = mysqli_fetch_array($res);   
    
    if($data['JWT'] == $jwt){
        $res = openssl_get_privatekey($secret_Key);
        $details = openssl_pkey_get_details($res);
        $publicKey = $details['key'];
        
        $token = null;
        try{
            // 传入ignore_expiration选项跳过过期校验
            $token = JWT::decode(
                $jwt, 
                new Key($publicKey, 'RS256'),
                ['ignore_expiration' => true]
            );
        }catch ( \Firebase\JWT\ExpiredException $exception ){
            // 过期异常已被忽略,无需额外处理
        }catch(SignatureInvalidException $e){
            // 签名无效,直接拒绝
            return false;
        }catch(BeforeValidException $e){
            // 令牌未到生效时间,拒绝
            return false;
        }catch(InvalidArgumentException $e){
            // 令牌格式错误,拒绝
            return false;
        }
        
        // 校验令牌核心字段有效性
        if (!$token || $token->iss !== $domainName || $token->uid !== $userID || $token->created !== $data['created']){
            return false;           
        }else{
            return true;            
        }
    }
    return false;
}

function generateJWT($con,$userID,$cretedTime) {
    $domainName = "firebase-XXXXX-XXXXX@XXXXX-XXXXX-XXXXX.iam.gserviceaccount.com";
    $secret_Key  = "-----BEGIN PRIVATE KEY-----\XXXXXXX--XXXXX---END PRIVATE KEY-----\n";
    
    $date   = time();

    $request_data = [
        'iss'  => $domainName, 
        'sub' => $domainName,
        'aud' => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
        'iat'  => $date,
        'exp' => $date+(60*60),
        'uid' => $userID,
        'created' => $cretedTime,
    ];
    
    $newToken = JWT::encode($request_data,$secret_Key,'RS256');
    // 修复SQL注入风险:使用预处理语句
    $sqlQuery = "UPDATE `sample` SET  `JWT` = ? WHERE  `id` = ?";
    $stmt = mysqli_prepare($con, $sqlQuery);
    mysqli_stmt_bind_param($stmt, "si", $newToken, $userID);
    
    if(mysqli_stmt_execute($stmt)){
        return $newToken; 
    }else {
        return 'Unable To Process';
    }
}       
?>

关键说明

  • ignore_expiration仅跳过exp字段的过期校验,令牌的签名有效性、iat生效时间等核心校验仍会执行,确保令牌未被篡改。
  • 必须保留iss、uid、created等自定义字段的校验,避免非法令牌通过验证。
  • 原代码存在SQL注入风险,已修改为预处理语句,这是生产环境的必要安全措施。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:42:03