您的位置:

JWT生成:从基础到实战

一、JWT生成token

JWT(JSON Web Token)是一个开放的标准,定义了用于在各方之间安全地传输声明的方式。在这个标准中,JWT用于在用户和身份验证之间传递信息,并且可以使用密钥对其签名,以便确保已传递的信息不会被篡改。JWT由头部、载荷和签名组成,用于生成token。

<?php
// 头部
$header = array(
    'alg' => 'HS256', // 签名算法
    'typ' => 'JWT'
);
$header = json_encode($header);
$header = base64_encode($header);
// 载荷
$payload = array(
    'sub' => '1234567890', // 主题
    'name' => 'John Doe', // 姓名
    'iat' => 1516239022 // 签发时间
);
$payload = json_encode($payload);
$payload = base64_encode($payload);
// 签名
$signature = hash_hmac('SHA256', "$header.$payload", 'mysecret', true);
$signature = base64_encode($signature);
// JWT token
$token = "$header.$payload.$signature";
?>

二、JWT生成流程

JWT生成流程主要包括三个步骤:头部、载荷和签名。

头部包含两个字段:alg表示签名算法,typ表示令牌类型,这两个字段会以JSON结构进行编码,然后通过base64Url编码。

载荷包含要传递的信息,比如用户ID、角色、权限等,和一些元数据,比如过期时间、签发时间等。与头部一样,载荷也要以JSON结构进行编码,然后通过base64Url编码。

签名是用于验证token是否被篡改的关键步骤。签名需要使用头部、载荷以及密钥。签名算法可以是HS256、HS384或HS512等。首先需要使用指定的算法生成一个签名,然后也需要通过base64Url编码。最后,将编码后的头部、载荷和签名用点号连接起来,形成完整的JWT。

三、JWT生成规则

生成JWT token的各个部分需要遵循一定的规则。

头部和载荷都要用JSON编码,然后通过base64Url编码。注意,base64Url编码需要去掉=符号、将+替换为-、将/替换为_。

签名需要使用指定的算法,并且需要使用到密钥。密钥需要妥善保管,不要泄露。在生成签名的过程中,需要使用头部和载荷的JSON编码结果、密钥以及指定的算法。签名的结果同样需要进行base64Url编码。

四、JWT生成token原理

生成JWT token的原理就是利用JSON Web Signature(JWS)规范实现的。JWS使用到两个相互独立的加密算法,一个用于生成签名,一个用于对消息进行加密,以确保其完整性和机密性。在生成JWS中的签名时,需要使用到Hash-based Message Authentication Code(HMAC),这种机制既可以作为签名算法,也可以在一些加密算法之上进行使用。

在生成JWT token时,可以使用不同的密钥对头部、载荷、签名进行签名。因此,密钥的管理是保证JWT token安全的关键。同时,在使用JWT token时,需要进行验证签名,否则JWT token可能会被篡改。

五、JWT生成的token格式

JWT生成的token格式包含三个部分:头部、载荷和签名,它们之间以点号(.)分隔开来。

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9.5upIKvc5ClYFkTYW7qJBE0LjYOcJLhUkLCRbRgB0jHU

头部和载荷都是基于JSON进行编码,并使用base64Url编码进行处理。签名则是对头部、载荷和密钥进行签名,生成的结果也是使用base64Url编码进行处理。

六、JWT生成token的算法

JWT生成token的算法有多种,包括HS256、HS384、HS512等。这些算法都是基于HMAC的,其中HS代表HMAC with SHA。

以HS256算法为例,它在计算签名时会使用到头部和载荷的base64Url编码形式,以及一个密钥。在计算签名时,需要首先将头部和载荷使用点号(.)连接起来,然后通过指定的算法(HMAC-SHA256)生成签名。生成的签名并不是使用base64Url编码的字符串,而是一段原始的二进制数据,需要再次进行base64Url编码。最后,将base64Url编码后的头部、载荷和签名用点号(.)连接起来,就生成了一个JWT token。

<?php
function generateJWTToken($payload, $secret) {
    $header = base64_encode(json_encode(array(
        "alg" => "HS256",
        "typ" => "JWT"
    )));
    $payload = base64_encode(json_encode($payload));
    $signature = base64UrlEncode(hash_hmac("SHA256", "$header.$payload", $secret, true));
    return "$header.$payload.$signature"; 
}

function verifyJWTToken($token, $secret) {
    list($header, $payload, $signature) = explode(".", $token);
    $signature2 = base64UrlEncode(hash_hmac("SHA256", "$header.$payload", $secret, true));
    return $signature == $signature2;
}

function base64UrlEncode($input) {
    return str_replace("=", "", strtr(base64_encode($input), "+/", "-_"));
}
?>

七、JWT生成token退出登录

通常,JWT token的有效期比较短,如果需要退出登录,只需要让客户端删除该token即可。由于JWT token不需要在服务器端保存状态,因此退出登录的过程也比较简单。

八、JWT生成token有效期选取

JWT token的有效期需要根据具体的业务需求进行选择。有效期过短可能会对用户的体验产生不良影响,过长则可能会存在安全隐患。

一般来说,JWT token的有效期可以设置为几十分钟到几小时,具体取决于用户的操作习惯。在设置有效期时,同时应该考虑到token的生成和验证的开销,以避免对服务器性能的影响。

总结

JWT是一种用于在各方之间安全传输信息的标准,可以用于实现身份验证、资源访问控制等功能。生成JWT token需要遵循一定的规则,包括JSON编码、base64Url编码、签名等。在生成和使用JWT token时,需要注意密钥的保密和签名的验证。同时,在设置JWT token的有效期时,需要考虑到用户体验和服务器性能的因素。