JWT理解
JWT由三个部分组成,基于token的身份验证可以替代传统的cookie+session身份验证方法。三个部分分别如下:
header.payload.signature
header部分组成
{ "typ":"JWT", "alg":"HS256" }
这就是一个json串,两个字段都是必须的,alg
字段指定了生成signature
的算法,默认值为 HS256
,可以自己指定其他的加密算法,如RSA
.经过base64encode
就可以得到 header.
payload 部分组成
playload 基本组成部分,还可以自己添加一些字段:
$payload=[ 'iss' => $issuer, //签发人 'iat' => $_SERVER['REQUEST_TIME'], //签发时间 'exp' => $_SERVER['REQUEST_TIME'] + 7200 //过期时间 'uid'=>1111 ];
payload
也是一个json数据,是表明用户身份的数据,可以自己自定义字段,很灵活。经过json_encode
和base64_encode
就可得到payload
signature组成部分
将 header
和 payload
使用header中指定的加密算法加密,secret是自己定义的秘钥。用于验证数据签名。
官网实例:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
实例:
<?php class JWK{ // 生成token public static function create_token($header,$payload,$secret){ $header_str = self::encode($header); $payload_str = self::encode($payload); $jwt_str = $header_str.'.'.$payload_str; return $jwt_str.'.'.self::create_signature($jwt_str,$secret,$header['alg']); } // 编码 public static function encode($json){ return base64_encode(json_encode($json)); } // 解码 public static function decode($content){ return json_decode(base64_decode($content),true); } // 创建签名 public static function create_signature($jwt_str,$secret,$type){ return hash($type,$jwt_str.'.'.$secret); } // 验证签名 public static function check_signature($str,$secret){ $arr = explode('.',$str); if( count($arr)===3 ){ $header = self::decode($arr[0]); $signature = self::create_signature($arr[0].'.'.$arr[1],$secret,$header['alg']); if( $signature===$arr[2] ){ return true; }else{ return false; } }else{ return false; } } // 获取结果 public static function get_result($str){ $arr = explode('.',$str); if( count($arr)===3 ){ return [ 'header' => self::decode($arr[0]), 'payload' => self::decode($arr[1]), 'signature' => $arr[2] ]; }else{ return false; } } } $secret = '464646413132aaa'; $header = [ 'alg' => 'sha256', 'uid' => '1', ]; $payload = [ 'name' => 'ricky', 'content' => 'nobody' ]; // 创建token 只要攻击者不知道secret是无法伪装token的,所以secret必须保护好 $token = JWK::create_token($header,$payload,$secret); // 验证token签名 if( JWK::check_signature($token,$secret) ){ // 获取解码token内容 if( $res = JWK::get_result($token) ){ echo json_encode($res); } }