JSON Web令牌或JWT由三部分组成:
- 标头:包含一些关于令牌本身的元数据。
- 有效负载:包含我们想要编码到令牌中的数据,因此我们想要在这里编码的数据越多,JWT就越大。
- 签名。
头两部分,即头和有效载荷,只是将被编码但不加密的纯文本。
所以任何人都可以解码并阅读,我们不能在这里存储任何敏感数据。但这一点都不成问题,因为在第三部分中,签名是事情真正有趣的地方。签名是使用头、有效负载和保存在服务器上的密码创建的。
整个过程称为签署Json Web令牌。签名算法采用标头、有效负载和密钥来创建唯一签名。所以只有这些数据加上秘密才能创建这个签名。然后,这些签名与标头和有效载荷一起构成JWT,然后发送给客户端。
一旦服务器收到JWT以授予对受保护路由的访问权限,它需要进行验证,以确定用户是否真的是他声称的用户。换句话说,它将验证是否没有人更改令牌的标头和有效负载数据。因此,这个验证步骤将检查是否没有第三方实际更改Json Web Token的标头或有效负载。
那么,这个验证实际上是如何工作的呢?嗯,这实际上很简单。一旦接收到JWT,验证将获取其头部和有效载荷,并与仍保存在服务器上的机密一起,基本上创建一个测试签名。
但是首次创建JWT时生成的原始签名仍然在令牌中,对吗?这就是验证的关键。因为现在我们要做的就是将测试签名与原始签名进行比较。如果测试签名与原始签名相同,则表示有效负载和标头未被修改。
因为如果它们被修改了,那么测试签名就必须不同。因此,在这种情况下,如果数据没有更改,我们可以对用户进行身份验证。当然,如果这两个签名实际上是不同的,那么这意味着有人篡改了数据。通常通过尝试更改有效载荷。但是,操纵有效载荷的第三方当然无权获得该秘密,因此他们无法签署JWT。因此,原始签名永远不会对应于操纵的数据。因此,在这种情况下,验证总是会失败。这是使整个系统工作的关键。正是魔法使JWT如此简单,但也非常强大。
现在让我们使用nodejs进行一些练习:
配置文件非常适合存储JWT SECRET数据。使用标准的HSA256加密进行签名,密钥至少应为32个字符长,但越长越好。
config.env:
JWT_SECRET=my-32-字符-超安全和超长机密//90天后,JWT将不再有效,即使签名者是正确的,并且一切都匹配。JWT_EXPIRES_IN=90
现在使用命令安装JWT
npm i jsonwebtoken
例如,用户注册后将JWT令牌传递给他,这样他就可以保持登录状态并访问资源。
exports.signup=catchAsync(异步(req、res、next)=>{const newUser=等待User.create({名称:req.body.name,电子邮件:req.body.email,密码:req.body.password,密码确认:req.body.passwordConfirm,});const标记=jwt.sign({id:newUser._id},process.env.jwt_SECRET{expiresIn:处理版本。JWT_EXPIRES_IN公司,});res.status(201).json({status:'成功',令牌,数据:{新用户,},});});
输出:
在我看来,不要在第三方的帮助下生成你的超机密密钥,因为你再也不能说这是秘密了。只需使用键盘。