JWT的原理详解和使用

JWT(JSON Web Token) 是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。JWT 可以使用密钥(使用 HMAC算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。

一、JWT的原理

JWT是一种服务端向客户端发放令牌的认证方式。当客户端使用用户名和密码登录时,服务端会生成一个包含用户信息的JWT令牌,并将其返回给客户端。客户端在后续的请求中只需携带这个令牌,服务端通过验证令牌来确认用户的身份,从而实现对用户的身份验证和授权。

二、JWT的结构

JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

1、头部(Header)

头部描述了JWT的元数据,包括算法(alg)和类别(typ)等信息。其中,alg描述了用于签名的算法,例如HMAC SHA256(HS256)或者RSA;typ表示令牌类型,通常设置为JWT,表示这是一个JWT类型的令牌。

jwt的头部由两部分信息组成:

  • typ:声明类型,这里是jwt
  • alg:声明加密的算法 通常直接使用 HMAC SHA256
{
  "alg": "HS256",
  "typ": "JWT"
}

然后,将此 JSON 经过Base64Url编码,形成 JWT 的第一部分。

2、载荷(Payload)

令牌的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型:已注册公开私有声明。

  • 注册声明:这些是一组预定义的声明,它们不是强制性的,但建议使用,以提供一组有用的、可互操作的声明。其中一些是: iss(颁发者)、 exp(到期时间)、 sub(主题)、 aud(受众)等。

    请注意,由于 JWT 力求紧凑,因此声明名称只有三个字符。

  • 公开声明:这些声明可以由使用 JWT 的用户随意定义。但为了避免冲突,它们应该在IANA JSON Web Token Registry中定义,或定义为包含抗冲突命名空间的 URI。

  • 私人声明:这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公开声明。

示例有效载荷可能是:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

然后对有效负载进行Base64Url编码以形成 JSON Web Token 的第二部分。

请注意,对于签名令牌,此信息虽然受到防篡改保护,但任何人都可以读取。除非已加密,否则不要将机密信息放入 JWT 的有效负载或标头元素中。

3、签名(Signature)

要创建签名部分,您必须获取编码的标头、编码的有效负载、秘密、标头中指定的算法,然后对其进行签名。

例如,如果您想使用 HMAC SHA256 算法,则签名将按以下方式创建:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

签名用于验证消息在传输过程中未被更改,并且,对于使用私钥签名的令牌,它还可以验证 JWT 的发送者是否是其所述的那个人。

三、JWT的优点

  1. 可扩展性:JWT的载荷部分可以自定义,可以根据具体需求添加额外的用户信息,实现灵活的身份验证和授权。
  2. 可靠性:JWT通过数字签名的方式保证了其完整性和真实性,可以有效防止令牌被篡改或伪造。
  3. 安全性:JWT的签名过程使用了加密算法,保证了令牌的安全性。同时,JWT的令牌是无状态的,即服务端不需要存储令牌信息,降低了安全风险。

四、JWT的应用场景

JWT在许多场景下都有广泛的应用,例如:

  1. 单点登录(SSO):JWT可以用于实现单点登录功能,用户只需登录一次即可访问多个应用,提高了用户体验。
  2. API认证:JWT可以作为API的身份验证和授权机制,保护API资源的安全。
  3. 分布式系统:在分布式系统中,JWT可以方便地实现跨服务之间的身份验证和授权。

五、 JWT安装

 在项目根目录中运行以下命令来安装Firebase的PHP JWT库:

composer require firebase/php-jwt

六、 JWT使用

<?php
 
require_once 'vendor/autoload.php'; // 引入composer的autoload文件
 
use Firebase\JWT\JWT;
 
// 要创建的JWT的密钥,保密
$key = "your_secret_key";
 
// 载体中的claims数据
$payload = [
    "iss" => "issuer",  // 签发者
    "iat" => time(),    // 签发时间
    "exp" => time() + 3600 // 过期时间
];
 
// 生成Token
$token = JWT::encode($payload, $key);
 
// 输出Token
echo "JWT: " . $token . "\n";
 
// 验证和解码Token
try {
    // 解码Token
    $decoded = JWT::decode($token, $key, array('HS256'));
    print_r($decoded);
} catch (Exception $e) {
    echo 'Invalid token: ' . $e->getMessage() . '\n';
}
 
?>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_68949064

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值