我目前正在学习使用PHP的JWT实现,并希望使用JWT令牌代替我的RESTful应用程序的会话.
在签名创建期间,我正在做这样的事情
token = base64Header + '.' + base64Payload + '.' + signature
Run Code Online (Sandbox Code Playgroud)
这里我们只使用base64 Payload.如果我粘贴到https://jwt.io/#debugger这样的网站,Payload就会被解密(即使签名错误).
我的问题,
下面是我写的示例代码
<?php
$headers = base64_encode(json_encode([
"typ" => "JWT",
"alg" => "HS256"
]));
$claims = base64_encode(json_encode([
"sub" => "1234567890",
"name" => "John Doe",
"admin" => true,
"jti" => "870a3de5-ea7b-4062-abef-11180e530f5a",
"iat" => 1492603378,
"exp" => 1492606978
]));
$payload = $headers.".".$claims;
$signature = base64_encode(hash_hmac("sha256", $payload, 'secret', true));
$encodedJWT = $payload.".".$signature;
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6Ijg3MGEzZGU1LWVhN2ItNDA2Mi1hYmVmLTExMTgwZTUzMGY1YSIsImlhdCI6MTQ5MjYwMzM3OCwiZXhwIjoxNDkyNjA2OTc4fQ.nvw-bAUgr7H_xr3q8_Yz8rCNtMohtn2YlCmcLoLBWlc
Run Code Online (Sandbox Code Playgroud)
dav*_*mey 11
如果我粘贴到https://jwt.io/#debugger这样的网站,Payload就会被解密(即使签名错误).
第三方无法验证签名,因为它们没有密钥.有效载荷不会被解密 - 它会被解码.
理想情况下,你应该不敏感数据存储在有效载荷,因为载荷仅仅是base64编码和加密.这意味着获得令牌的任何人都可以通过简单的base64解码来查看有效负载的内容.
如果您在Web浏览器的本地存储中有令牌,并且您的站点有XSS漏洞,那么窃取令牌就变得微不足道了.攻击者有一个有效的JWT(希望很快就会过期)已经够糟糕了,但是如果它包含敏感数据那么你真的遇到了麻烦.想象一下,必须通知您网站上的所有用户,他们现在必须更改关于他们自己的各种敏感数据,因为潜在的质量妥协.
保持JWT轻量级.存储用户ID,他们的角色/资助与系统.如果您觉得必须向有效负载添加敏感数据,请尝试重新考虑您的解决方案.
不,不仅有签名的 JWT (JWS - RFC 7515),还有加密的 JWT (JWE - RFC 7516)。
当 JWT 被加密时,您可以安全地共享敏感数据(除非算法或密钥被泄露)。
但是在您的示例中,我看不到敏感数据,因此我想知道在您的情况下使用 JWE 是否真的很重要。我强烈建议您阅读这篇关于 JWT 和会话以及为什么不应该将它们用于此目的的博客文章(另请参阅第 2 部分)。
如果您真的想使用 JWE,那么我编写了一个 PHP 库,该库已经能够加载和创建任何类型的 Jose (JWS/JWE),并且它支持RFC 7518 中的几乎所有开箱即用的算法。可能存在其他库,但没有引用列表(https://jwt.io/仅列出 JWS 实现)。
据我了解,您正在尝试拥有一个完整的stateless服务器,因此您甚至希望在令牌中存储敏感数据。
但是您的服务器不能完全无状态。因为对于注销功能,您必须有黑名单或白名单才能使令牌无效。所以在每个请求中你必须接触数据库。如果您没有black list或white list,即使用户注销,令牌仍然有效。
因此,最好从数据库中获取敏感数据,因为您应该根据每个请求访问您的数据库。
| 归档时间: |
|
| 查看次数: |
4086 次 |
| 最近记录: |