在 Laravel 中验证 Node 生成的 JWT

Posted

技术标签:

【中文标题】在 Laravel 中验证 Node 生成的 JWT【英文标题】:Verifying JWT generated by Node in Laravel 【发布时间】:2016-12-30 09:21:48 【问题描述】:

我正在node-jsonwebtoken 中的身份验证服务器 (Node.js) 上生成一个令牌,该令牌将传递给 API (php Laravel) 并由 tymondesigns/jwt-auth 验证。

由 tymondesigns/jwt-auth 生成的令牌将通过以下方式成功验证 它自己的验证函数,node-jsonwebtoken 和jwt.io。 node-jsonwebtoken 生成的令牌将通过其自身的验证函数jwt.io 验证成功,但不是 tymondesigns/jwt-auth

在 Laravel 服务器上,当我尝试验证由 node-jsonwebtoken 生成的令牌时出现以下错误:

TokenInvalidException in NamshiAdapter.php line 71:
Token Signature could not be verified.

当我在jwt.io 查看有效载荷时,它们看起来完全一样。我什至尝试通过传递与工作令牌生成的相同的 iat、sub、iss、exp、nbf 和 jti 在节点服务器上生成完全相同的令牌,但 tymondesigns/jwt-auth 仍然不会接受它。

是否还有其他原因可能导致此问题,但在解码信息中不可见?我也不是 100% 确定 jti 是如何工作的。也许有什么东西阻止了它的工作?

node-jsonwebtoken (7.1.9)、tymon/jwt-auth (0.5.9)、namshi/jose (5.0.2)

【问题讨论】:

【参考方案1】:

在我的情况下,我在有效负载中有一个 url。默认情况下,PHP 在编码为 JSON 时会转义斜杠,而 Node.js 不会。当在 PHP 中生成验证 JWT(带有那些额外的反斜杠)时,最终的哈希值当然不会匹配,因为有效负载只是不同的。解决方案是在 JWT 库中转换为 JSON 时使用 JSON_UNESCAPED_SLASHES 标志,我使用的是https://github.com/namshi/jose,所以我创建了一个像这样的简单类:

use Namshi\JOSE\SimpleJWS;

class SimpleJWSWithEncodeOptions extends SimpleJWS

    protected static $encodeOptions = 0;

    public static function setEncodeOptions($options)
    
        self::$encodeOptions = $options;
    

    /**
     * Generates the signed input for the current JWT.
     *
     * @return string
     */
    public function generateSigninInput()
    
        $base64payload = $this->encoder->encode(json_encode($this->getPayload(), self::$encodeOptions));
        $base64header  = $this->encoder->encode(json_encode($this->getHeader(), self::$encodeOptions));

        return sprintf("%s.%s", $base64header, $base64payload);
    

那么它可以像这样使用:

SimpleJWSWithEncodeOptions::setEncodeOptions(JSON_UNESCAPED_SLASHES);
$jws = SimpleJWSWithEncodeOptions::load($token);
$jws->verify($key);
$data = $jws->getPayload();

这个问题对我的有效负载内容非常具体,但它可以帮助某人

【讨论】:

【参考方案2】:

正如 Spomky 所提到的,原因是 namshi/jose 中的一个与 iss 声明相关的错误。它在 tymon/jwt-auth 1.0.0-alpha.2 使用的7.0 中得到解决。但是,由于目前没有记录安装 1.0.0-alpha.2 的方法,我们可能必须等待稳定版本。

在此之前,由于问题和错误与 iss 声明有关,因此从 required_claims 中删除 iss 要求并在没有它的情况下生成令牌可以暂时解决问题。

【讨论】:

【参考方案3】:

namshi/jose 库的最新版本是 7.0。 所有ESxxx 算法还有一个已知错误。

如果您无法使用该库验证签名,您可以尝试使用另一个库。 我开发了a library,它支持与 JWT 相关的 RFC 中描述的所有功能,包括加密支持。

【讨论】:

以上是关于在 Laravel 中验证 Node 生成的 JWT的主要内容,如果未能解决你的问题,请参考以下文章

在 jwt-auth laravel 中获取自定义声明

在 Laravel 中验证多个用户生成的标签

Laravel 默认登录身份验证生成意外错误

Laravel 通过生成的令牌进行身份验证,无需护照和 jwt

使用 Captcha 扩展包 为 Laravel 5 应用生成验证码

使用由 jose4j 生成的令牌在 node.js 中使用 jsonwebtoken 验证 JWT 失败