JWT(JSON Web Token)是一种轻量级、自包含、用于身份验证和授权的令牌,它将用户信息(如用户ID、角色和权限等)编码到一个 JSON 对象中,然后对其进行数字签名,从而生成一个经过签名的令牌。本文将详细介绍 JWT 的概念、结构,并讲解如何在 WordPress 中实现 JWT 的生成和验证。
什么是 JWT?
JWT 是一种安全机制,常用于无状态的 RESTful API 认证。它允许服务器对传递的令牌进行验证,从而保证用户身份的真实性。由于 JWT 在客户端和服务器之间传输时是加密的,因此可以防止信息被篡改。
JWT 的结构
JWT 由三部分组成:Header(头部)、Payload(负载)和 Signature(签名),它们通过点(.)连接,形成一个完整的 JWT,如下所示:
header.payload.signature
- Header(头部)
Header 是一个 JSON 对象,包含两个属性:alg
(签名算法)和 typ
(令牌类型)。常见的签名算法有 HS256、RS256 等。Header 会被 Base64Url 编码,生成如下字符串:
{
"alg": "HS256",
"typ": "JWT"
}
- Payload(负载)
Payload 也是一个 JSON 对象,包含用户信息和其它业务数据。声明可以是预定义的(如 iss
、exp
、sub
等),也可以是自定义的。Payload 同样会被 Base64Url 编码,生成如下字符串:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
预定义字段包括:
iss
(issuer):签发人sub
(subject):主题aud
(audience):受众exp
(expiration time):过期时间nbf
(Not Before):生效时间iat
(Issued At):签发时间jti
(JWT ID):唯一身份标识
- Signature(签名)
签名用于保证 JWT 的完整性和安全性。它将 Header、Payload 和一个密钥(Secret)通过签名算法进行加密。示例如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
生成的签名会被附加到 JWT 的末尾,形成完整的 JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
在 WordPress 中实现 JWT
在 WordPress 中实现 JSON Web Token (JWT) 身份验证涉及以下步骤:
步骤 1:安装 JWT Authentication 插件
- 登录到你的 WordPress 管理后台。
- 导航到 插件 > 安装新插件。
- 搜索 JWT Authentication for WP REST API。
- 安装并激活该插件。
步骤 2:配置插件
- 激活插件后,导航到 设置 > JWT Authentication。
- 在设置页面中,你需要配置以下选项:
- Secret Key:这是用于签署 JWT 的密钥。你可以在
wp-config.php
文件中添加以下代码行来设置密钥:define('JWT_AUTH_SECRET_KEY', 'your-secret-key');
- Enable CORS:如果你有跨域请求的需求,可以启用这个选项。
- Secret Key:这是用于签署 JWT 的密钥。你可以在
步骤 3:配置 .htaccess 文件
在你的网站根目录下的 .htaccess
文件中添加以下规则:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
</IfModule>
步骤4:生成 JWT
以下是一个用于生成 JWT 的函数:
function wpjam_generate_jwt($payload, $secret='', $header=[]){
// 无法生成没有设置过期时间的 JWT
if(empty($payload['exp'])){
return false;
}
$header = wp_parse_args($header, [
'alg' => 'HS256',
'typ' => 'JWT'
]);
if($header['alg'] == 'HS256'){
$header = base64_urlencode(wpjam_json_encode($header));
$payload = base64_urlencode(wpjam_json_encode($payload));
$jwt = $header.'.'.$payload;
$secret = $secret ?: wp_salt();
return $jwt.'.'.base64_urlencode(hash_hmac('sha256', $jwt, $secret, true));
}
}
上述代码首先对 Header 和 Payload 进行 JSON 编码和 URL 安全的 Base64 编码。生成签名的密钥(Secret)如果为空,则使用 WordPress 默认的盐值函数来生成。最后将 Header、Payload 和生成的签名通过点(.)连接起来,形成一个完整的 JWT。
步骤5:验证 JWT
验证 JWT 的过程是生成的反过程,具体实现如下:
function wpjam_verify_jwt($token, $secret=''){
$tokens = explode('.', $token);
if(count($tokens) != 3){
return false;
}
list($header, $payload, $sign) = $tokens;
$jwt = $header.'.'.$payload;
$secret = $secret ?: wp_salt();
$header = wpjam_json_decode(base64_urldecode($header));
$payload= wpjam_json_decode(base64_urldecode($payload));
if(empty($header['alg']) || $header['alg'] != 'HS256'){
return false;
}
if(!hash_equals(base64_urlencode(hash_hmac('sha256', $jwt, $secret, true)), $sign)){
return false;
}
// 签发时间大于当前服务器时间验证失败
if(isset($payload['iat']) && $payload['iat'] > time()){
return false;
}
// 该 nbf 时间之前不接收处理该 Token
if(isset($payload['nbf']) && $payload['nbf'] > time()){
return false;
}
// 没有设置过期时间,或过期时间小于当前服务器时间验证失败
if(empty($payload['exp']) || $payload['exp'] < time()){
return false;
}
return $payload;
}
上面的代码首先通过点(.)将 JWT 分割成 Header、Payload 和 Signature 三段,然后对 Header 和 Payload 进行 URL 安全的 Base64 解码和 JSON 解码。通过签名的密钥最后验证签名的正确性。如果签名有效并且令牌未过期,则返回 Payload 数据。
步骤6:Base64 URL 编码和解码函数
在上述过程中用到的 URL 安全的 Base64 编码和解码函数 base64_urlencode
和 base64_urldecode
也需要定义:
function base64_urlencode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64_urldecode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
总结
通过 wpjam_generate_jwt
和 wpjam_verify_jwt
这两个函数,可以在 WordPress 中实现 JWT 的生成和验证。JWT 提供了一种安全、无状态的方式来认证用户,在现代 Web 开发中越来越流行。
暂无评论内容