最新公告
  • 欢迎您光临源码库,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入
  • 如何在 WordPress 中生成和验证 JWT(JSON Web Token)

    终于在 WPJAM Basic 中实现了 JWT 登录和认证功能,今天就整理一下,首先按照惯例做一些 JWT 的介绍。

    什么是 JWT

    JWT(JSON Web Token)是一种轻量级的、自包含的、通常用于身份验证和授权的令牌,它将用户信息(如用户ID、角色和权限等)编码到一个 JSON 对象中,然后对其进行数字签名,从而生成一个经过签名的令牌。

    如何在 WordPress 中生成和验证 JWT(JSON Web Token)插图源码资源库

    由于 JWT 在客户端和服务器之间传输时是加密的,因此服务器可以轻松验证该令牌的有效性和真实性。JWT 常用于无状态的 RESTful API,作为访问受保护资源的凭据,可以在每次请求时附加在请求头中,下图是使用 JWT 的一个常见的交互流程:

    如何在 WordPress 中生成和验证 JWT(JSON Web Token)插图源码资源库

    JWT 的结构

    JWT(JSON Web Token)由三部分组成,分别是:Header(头部)、Payload(负载)和 Signature(签名)。

    如何在 WordPress 中生成和验证 JWT(JSON Web Token)插图源码资源库

    这三部分使用点(.)分隔,合并为一个字符,如下所示:

    header.payload.signature

    Header(头部)

    Header 是一个 JSON 对象,通常包含两个属性alg 和 typalg 属性表示签名算法(如 HS256、RS256 等),typ 属性表示令牌类型,通常为 “JWT”。Header 会被 Base64Url 编码,得到一个字符串。例如:

    {
      "alg": "HS256",
      "typ": "JWT"
    }

    Payload(负载):

    Payload 是一个 JSON 对象,包含一些“声明”(Claim),用于传递用户信息和其他业务数据,声明可以是预定义的(如 iss、exp、sub 等),也可以是自定义的,Payload 会被 Base64Url 编码,得到一个字符串。例如:

    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    }

    下面这 7 个字段都是由官方所定义的,也就是预定义(Registered claims)的,但并不都是必需的,

    • iss (issuer):签发人
    • sub (subject):主题
    • aud (audience):受众
    • exp (expiration time):过期时间
    • nbf (Not Before):生效时间,在此之前是无效的
    • iat (Issued At):签发时间
    • jti (JWT ID):唯一身份标识,主要用来作为一次性 token,从而回避重放攻击

    另外声明名称只有三个字符,因为 JWT 意味着是紧凑的。

    Signature(签名):

    签名用于保证 JWT 的完整性和安全性,它是将 Header、Payload 和一个密钥(Secret)通过签名算法进行加密得到的,签名可以防止 JWT 被篡改和伪造,例如,使用 HMAC-SHA256 算法生成签名的方法如下:

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

    将 HeaderPayload 和 Signature 用点(.)连接起来,就得到了一个完整的 JWT,例如:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

    WordPress 中实现 JWT

    通过上面 JWT 的介绍和 JWT 结构可知,生成 JWT,就是通过签名算法和一个用于生成签名的密钥(Secret)对 Payload 生成签名:我们为了方便就只支持 SHA256 签名算法:

    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 。

    那么怎么验证 JWT 呢,验证的过程就是生成的反过程:首先通过点(.)将 JWT 分割成 HeaderPayload 和 Signature 三段,然后对 Header 和 Payload 进行 URL 安全的 Base64 解码和JSON 解码,通过签名的密钥最后验证签名:

    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。

    wpjam_generate_jwt 和 wpjam_verify_jwt 这两个函数在 WPJAM Basic 中已经内置了,通过他们就可以在 WordPress 实现 JWT 的生成和验证了。

    特别提醒一下过程中用到的 URL 安全的 Base64 编码和解码函数 base64_urlencode 和 base64_urldecode 也是在 WPJAM Basic 中定义了。

    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!

    源码资源库 » 如何在 WordPress 中生成和验证 JWT(JSON Web Token)