在 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的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 通过生成的令牌进行身份验证,无需护照和 jwt