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

Firebase JWT decode报错:参数$headers无法按引用传递

Firebase JWT解码时“Argument #3 cannot be passed by reference”错误解决

问题场景

使用PHP版Firebase JWT库实现API认证,登录生成JWT后,调用其他接口解码Token时触发致命错误:

Fatal error:  Uncaught Error: Firebase\JWT\JWT::decode(): Argument #3 ($headers) cannot be passed by reference in /home/kuba/projects/jcubic/terminal/jwt/service.php:45

尝试将['HS512']改为array('HS512')后报错依旧,代码用于jQuery Terminal的JSON-RPC接口,Auth类作为Service对象的包装,登录获取Token后存入localStorage,作为其他方法的首个参数传递。

错误原因

Firebase JWT的decode方法第三个参数($headers)是按引用传递的,PHP语法规则不允许直接将字面量数组(如['HS512'])传递给按引用的参数,必须先将数组赋值给一个变量,再传递该变量。

解决方案

1. 修正valid_token方法

将允许的算法数组先赋值给变量,再传递给JWT::decode,同时修正Token生效时间的判断逻辑:

private function valid_token($jwt) {
    global $env;
    // 先将算法数组赋值给变量
    $allowed_algs = ['HS512'];
    $token = JWT::decode($jwt, $env['secret'], $allowed_algs);
    $now = new DateTimeImmutable();
    return $token->iss == $env['domain'] &&
      $token->nbf <= $now->getTimestamp() && // 修正nbf判断逻辑:当前时间不早于Token生效时间
      $token->exp > $now->getTimestamp();
}

2. 修复__call方法未定义变量问题

原代码中$methods变量未定义,需先声明允许调用的Service方法列表:

public function __call($method, $params) {
    $jwt = array_shift($params);
    if (!$this->valid_token($jwt)) {
        throw new Exception("Invalid Token");
    }

    // 定义允许调用的Service方法列表,替换为实际业务方法名
    $methods = ['getUserData', 'updateProfile'];
    if (!in_array($method, $methods)) {
        throw new Exception("Invalid method $method");
    }
    
    return call_user_func_array(array($this->service, $method), $params);
}

修正后的完整代码

$env = parse_ini_file('.env');

class Auth {
    private $service;
    public function __construct($service) {
        $this->service = $service;
    }
    public function login($user, $password) {
        global $env;
        if ($user != $env['user'] || $password != $env['password']) {
            return null;
        }
        
        $date = new DateTimeImmutable();
        $expire_at = $date->modify('+6 minutes')->getTimestamp();
        $payload = [
            'iat'  => $date->getTimestamp(),
            'iss'  => $env['domain'],
            'nbf'  => $date->getTimestamp(),
            'exp'  => $expire_at,
            'userName' => $user,
        ];
        return JWT::encode(
            $payload,
            $env['secret'],
            'HS512'
        );
    }
    private function valid_token($jwt) {
        global $env;
        $allowed_algs = ['HS512'];
        $token = JWT::decode($jwt, $env['secret'], $allowed_algs);
        $now = new DateTimeImmutable();
        return $token->iss == $env['domain'] &&
          $token->nbf <= $now->getTimestamp() &&
          $token->exp > $now->getTimestamp();
    }
    public function __call($method, $params) {
        $jwt = array_shift($params);
        if (!$this->valid_token($jwt)) {
            throw new Exception("Invalid Token");
        }

        // 替换为实际需要开放的Service方法名
        $methods = ['getUserData', 'updateProfile'];
        if (!in_array($method, $methods)) {
            throw new Exception("Invalid method $method");
        }
        
        return call_user_func_array(array($this->service, $method), $params);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:25:08