169 lines
3.3 KiB
PHP
169 lines
3.3 KiB
PHP
<?php
|
||
|
||
namespace utils;
|
||
|
||
class Jwt
|
||
{
|
||
private $typ = 'JWT';
|
||
|
||
#key用户生成secret
|
||
private $key = 'jSCq5heSuhDiuhSsad441wq6541SDA5415W6QE564dsda';
|
||
|
||
private $secret;
|
||
|
||
#加密算法
|
||
private $alg = 'HS256';
|
||
|
||
#签发者-payload组成部分
|
||
private $iss;
|
||
|
||
#过期时间-payload组成部分
|
||
private $exp;
|
||
|
||
#签发时间-payload组成部分
|
||
private $iat;
|
||
|
||
#用户基础信息-payload组成部分
|
||
private $user_info;
|
||
|
||
#过期多久之前有效
|
||
private $timeout = 7200;
|
||
|
||
public function __construct($config)
|
||
{
|
||
$this->config = $config;
|
||
$this->init();
|
||
}
|
||
|
||
private function init()
|
||
{
|
||
$this->iss = $this->config['iss'];
|
||
$this->exp = $this->config['exp'];
|
||
$this->iat = time();
|
||
}
|
||
|
||
/**
|
||
* 获取token
|
||
* @param array $user_info
|
||
* @return string
|
||
*/
|
||
public function getToken(array $user_info):string
|
||
{
|
||
//头信息
|
||
$header = [
|
||
'typ' => $this->typ,
|
||
'alg' => $this->alg
|
||
];
|
||
$base64_header = base64_encode(json_encode($header));
|
||
|
||
//有效载荷
|
||
$payload = [
|
||
'iss' => $this->iss,
|
||
'exp' => $this->exp,
|
||
'iat' => $this->iat,
|
||
'user_info' => $user_info,
|
||
];
|
||
$base64_payload = base64_encode(json_encode($payload));
|
||
|
||
//签名信息
|
||
$this->secret = $this->getSecret($user_info);
|
||
$signature = $base64_header . $base64_payload . $this->secret;
|
||
$base64_signature = $this->enc($this->alg, $signature);
|
||
|
||
$jwt_token = $base64_header . '.' . $base64_payload . '.' . $base64_signature;
|
||
return $jwt_token;
|
||
}
|
||
|
||
/**
|
||
* 校验token
|
||
* @param $jwt_token
|
||
* @return int
|
||
*/
|
||
public function checkToken($jwt_token)
|
||
{
|
||
$arr = explode('.', $jwt_token);
|
||
if (count($arr) < 3) {
|
||
return -1;
|
||
}
|
||
|
||
$base64_header = $arr[0];
|
||
$base64_payload = $arr[1];
|
||
$base64_signature = $arr[2];
|
||
|
||
$payload = json_decode(base64_decode($base64_payload), true);
|
||
if (!is_array($payload) || !isset($payload['exp']) || !isset($payload['iat']) || !isset($payload['user_info'])) {
|
||
return -2;
|
||
}
|
||
|
||
//生成签名,比较
|
||
$this->secret = $this->getSecret($payload['user_info']);
|
||
$tmp_signature = $base64_header . $base64_payload . $this->secret;
|
||
$tmp_base64_signature = $this->enc($this->alg, $tmp_signature);
|
||
|
||
if ($base64_signature !== $tmp_base64_signature) {
|
||
return -3;
|
||
}
|
||
|
||
// 是否过期
|
||
if ($payload['exp'] + $payload['iat'] - time() < 0) {
|
||
// token过期了
|
||
return -4;
|
||
} else {
|
||
// token没有过期
|
||
if ($payload['exp'] + $payload['iat'] - time() - $this->timeout < 0) {
|
||
return 201;
|
||
}
|
||
|
||
return 200;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取用户信息
|
||
* @param $jwt_token
|
||
* @return array|mixed
|
||
*/
|
||
public function getUserInfo($jwt_token)
|
||
{
|
||
$arr = explode('.', $jwt_token);
|
||
if (count($arr) < 3) {
|
||
return [];
|
||
}
|
||
|
||
$base64_payload = $arr[1];
|
||
|
||
$payload = json_decode(base64_decode($base64_payload), true);
|
||
if (!is_array($payload) || !isset($payload['user_info'])) {
|
||
return [];
|
||
}
|
||
|
||
return $payload['user_info'];
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取secret,保证每个用户的secret都不同
|
||
* @param $user_info
|
||
* @return string
|
||
*/
|
||
private function getSecret($user_info)
|
||
{
|
||
return md5($this->key . json_encode($user_info));
|
||
}
|
||
|
||
/**
|
||
* 加密
|
||
* @param $enc_type
|
||
* @param $content
|
||
* @return string
|
||
*/
|
||
private function enc($enc_type, $content)
|
||
{
|
||
if ($enc_type == 'HS256')
|
||
{
|
||
return hash('sha256', $content);
|
||
}
|
||
}
|
||
|
||
}
|