• 喜欢前端以及PHP的朋友们可以加PHP同好会QQ群 点击加入qq群
  • 最近在写一个项目---"小A微信托管平台",大家可以去帮忙测试一下!功能在不断完善中,敬请关注!点击进入
  • 本站使用了PHP8.1与HTTP2.0协议,速度简直超级快有木有?

JWT token 生成与验证

后端 Mr.Adam 4年前 (2021-02-24) 1224次浏览 已收录 0个评论

JWT token 生成与验证

JWT token 生成与验证

本文引用自https://jwt.io

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

尽管可以对 JWT 进行加密以提供双方之间的保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏在其他方的面前。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

以下是 JSON Web 令牌有用的一些方案:

JWT 的结构

JSON Web 令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔,分别是:

标头
有效载荷
签名
因此,JWT 通常如下所示。

xxxxx.yyyyy.zzzzz

让我们分解不同的部分。

标头

标头通常由两部分组成:令牌的类型(即 JWT)和所使用的签名算法,例如 HMAC SHA256 或 RSA。

例如:

{
  "typ": "JWT",
  "alg": "RS256",
  "jti": "c04df38514f2ea7b3580f93f8d8845b69e17d8a70d0c5aae5cbc823f456c60773346fc142af5635d"
}

typ 是 token 的类型
alg 是加密的算法
jti 是 jwt id
此 JSON 被 Base64Url 编码以形成 JWT 的第一部分。

有效载荷

令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。
例如:

{
  "aud": "2",
  "jti": "c04df38514f2ea7b3580f93f8d8845b69e17d8a70d0c5aae5cbc823f456c60773346fc142af5635d",
  "iat": 1614153428,
  "nbf": 1614153428,
  "exp": 1614758228,
  "sub": "1",
  "scopes": []
}

aud:Audience 代表谁拥有该 key,oauth2 里通常是 client_id
jti:jwt id
iat:issued at 时间戳
nbf:not valid before 时间戳
exp:过期时间戳
可能的值还有
iss:发行方
sub:主体内容
除了以上内容还可以包含自己的数据,例如name,请不要包含敏感内容
对有效载荷进行 Base64Url 编码,以形成 JSON Web 令牌的第二部分。

签名

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

例如,如果要使用 RS256 算法,则将通过 openssl 私钥创建签名:

function JWT() {
    $time = time();
    $header = ['alg' => 'RS256', 'typ' => 'JWT'];
    $claims = [
        'iss' => 'http://a.com', 
        'scope' => '*',
        'aud' => 'http://b.com', 
        'exp' => $time + 3600,
        'iat' => $time
    ];
    $msg = Base64URLEncode(json_encode($header)) . '.' . Base64URLEncode(json_encode($claims));
    $privateKey = "-----BEGIN PRIVATE KEY-----\nKEY\n-----END PRIVATE KEY-----\n";
    $sign = '';
    openssl_sign($msg, $sign, $privateKey, 'SHA256');
    return $msg . '.' . Base64URLEncode($sign);
}

function Base64URLEncode($input) {
    return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}

echo JWT();

校验 JWT token

校验 jwt token 则可以使用 openssl 公钥进行验签,校验代码如下:

$jwt = "xxx.yyy.zzz";
function rsa_verify($sign,$str,$public_key){
    $data = Base64URLDecode($sign);
    $publicKeyId = openssl_pkey_get_public($public_key);
    $result = openssl_verify($str, $data, $publicKeyId,"SHA256");
    openssl_free_key($publicKeyId);
    return $result === 1 ? true : false;
}
$arr = explode(".",$jwt);
$public_key = "-----BEGIN PUBLIC KEY-----\nKEY\n-----END PUBLIC KEY-----\n";
$is_verify = rsa_verify($arr[2].$arr[0].".".$arr[1],$public_key);
if($is_verify){
    echo "通过验证";
}else{
    echo "未通过验证";
}

jwt 的加密方式不同,则校验方式也不相同!


小 A 空间 , 版权所有丨如未注明转载 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明JWT token 生成与验证
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址