王新阳

wangxinyang

JSON 网络令牌JWT(JSON Web Token)

参考:https://zhuanlan.zhihu.com/p/12876076909

1、什么是JWT?
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间以 JSON 格式安全地传输信息。它通常用于身份验证和授权流程中,特别是在无状态的 RESTful API 和现代 Web 应用中。

2、什么时候应该使用 JSON Web Token?
以下是 JSON Web Token (JWT) 的一些适用场景:

授权(Authorization): 这是 JWT 最常见的用途。用户登录后,后续的每个请求都会携带 JWT,从而允许用户访问该令牌所授权的路由、服务和资源。单点登录(Single Sign On)是当前广泛使用 JWT 的一个功能,因为它具有较小的开销,并且可以轻松跨不同域名使用。
信息交换(Information Exchange): JWT 是在各方之间安全传输信息的一种好方式。由于 JWT 可以签名(例如,使用公钥/私钥对),你可以确认发送者的身份。此外,由于签名是基于头部(header)和负载(payload)计算得出的,你还可以验证内容是否被篡改。

3、JSON Web Token 的结构是什么?
在紧凑形式中,JSON Web Token(JWT)由三部分组成,各部分之间通过点号(.)分隔:

头部(Header)
负载(Payload)
签名(Signature)

JWT有效期可以在 $payload 中设置(建议),也可以通过在 $secretKey 原有秘钥后加日期,动态改变秘钥来实现

PHP生成和验证jwt

//生成JWT令牌
function jwt_create($payload, $secretKey){
	function base64url_encode($data){return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');}
	// 定义 Header、Payload 和密钥
	$header = array('alg' => 'HS256');

	// 编码 Header 和 Payload
	$headerEncoded = base64url_encode(json_encode($header));
	$payloadEncoded = base64url_encode(json_encode($payload));

	// 生成签名(HMAC-SHA256)
	$signatureInput = "$headerEncoded.$payloadEncoded";
	$signature = hash_hmac('sha256', $signatureInput, $secretKey, true);
	$signatureEncoded = base64url_encode($signature);

	// 组合完整 JWT
	$jwt = "$headerEncoded.$payloadEncoded.$signatureEncoded";
	return $jwt;
}
//验证JWT令牌并获取数据
function jwt_verify($jwt,$secretKey){
	function base64url_encode($data){return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');}
	function base64url_decode($data) {$padding = strlen($data) % 4; if($padding > 0){$data .= str_repeat('=', 4 - $padding);} return base64_decode(strtr($data, '-_', '+/'));}
	// 提取已生成的 JWT 各部分
	list($header, $payload, $signature) = explode('.', $jwt);

	// 重新计算签名
	$recomputedSignature = base64url_encode(
		hash_hmac('sha256', "$header.$payload", $secretKey, true)
	);

	// 比较签名
	if($signature === $recomputedSignature){
		$res=json_decode(base64url_decode($payload),true);
		if(is_array($res) && isset($res['userid']))return $res['userid'];
	}
	return false;
}
2025-11-15
2026-03-01 星期日 农历正月十三