You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Firebase/php-jwt生成JWT正常但无法验证,参数获取失败

解决JWT验证时无法获取Token的问题

我看到你在使用firebase/php-jwt库实现身份验证时,生成Token的环节没问题,但验证阶段卡在了Token获取上——你用$_SERVER['argv'][1]来获取Token,这是命令行运行PHP脚本时才会用到的参数,而你的验证接口是HTTP接口,所以会出现未定义警告,自然也拿不到Token。

核心问题分析

$_SERVER['argv']仅在PHP以CLI(命令行)模式运行时才会填充参数,比如你在终端执行php test2.php your-token$_SERVER['argv'][1]才会拿到your-token。但你是通过HTTP请求调用test2.php?action=stuff,这个数组是空的,所以必然报错。

正确的Token传递与获取方式(无Cookie/Session)

REST API中最标准的做法是通过HTTP请求头传递Token,具体用Authorization字段,格式为Bearer <你的JWT Token>。下面是修改后的验证逻辑:

步骤1:修改验证接口的Token获取代码

把原来的stuff分支代码替换成以下内容:

} else if($action == 'stuff'){
    // 从Authorization头获取Token
    $jwt = null;
    // 根据服务器环境获取请求头,Apache用apache_request_headers(),通用环境用getallheaders()
    $headers = function_exists('apache_request_headers') ? apache_request_headers() : getallheaders();
    
    if(isset($headers['Authorization'])){
        // 拆分Bearer标识和Token内容
        list($tokenType, $jwt) = explode(' ', $headers['Authorization'], 2);
        if(strtolower($tokenType) !== 'bearer'){
            http_response_code(400);
            $data_insert = array(
                "status" => "error",
                "message" => "无效的Token类型,请使用Bearer格式"
            );
            echo json_encode($data_insert);
            exit;
        }
    }

    if(empty($jwt)){
        http_response_code(401);
        $data_insert = array(
            "status" => "error",
            "message" => "未提供Token,请在Authorization头中携带Bearer格式的Token"
        );
        echo json_encode($data_insert);
        exit;
    }

    try {
        $decoded = JWT::decode($jwt, SECRET_KEY, array(ALGORITHM));
        // 验证成功,返回解码后的数据
        $data_insert = array(
            "status" => "success",
            "decoded_data" => (array)$decoded
        );
    }catch (Exception $e){
        http_response_code(401);
        $data_insert=array(
            "jwt" => $jwt,
            "status" => "error",
            "message" => $e->getMessage()
        );
    }
}

步骤2:确保CORS允许Authorization头

你的CORS处理部分需要明确允许Authorization头,否则前端发送这个头会被浏览器拦截。修改OPTIONS请求的头设置:

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    // 明确添加Authorization到允许的头列表,避免跨域拦截
    header("Access-Control-Allow-Headers: Content-Type, Authorization");
    exit(0);
}

测试验证接口

调用http://www.ismailcakir.com/jwt/test2.php?action=stuff时,在请求头中添加:

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxNTg2NDM4NTg4LCJuYmYiOjE1ODY0Mzg1OTgsImV4cCI6MTU4NjQzODY0OCwiZGF0YSI6eyJpZCI6MTEsImVtYWlsIjoiZnJlYWt5QGpvbGx5LmNvbSJ9fQ.NylRpDkb4cLMxMGAg9ovmLerNf0dLPBHegqmPRDRxlE

这样就能正确获取并验证Token了。

额外注意事项

  • 如果你不想用Authorization头,也可以通过URL参数传递(比如?token=<你的JWT>),但这种方式不安全,容易被日志记录,不推荐。
  • 确保你的SECRET_KEY足够复杂,不要用示例中的Super-Secret-Key,避免被破解。
  • 处理Token过期、签名错误等异常时,返回对应的HTTP状态码(401表示未授权),方便前端处理。

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

火山引擎 最新活动