1.引入php-jwt包
composer require firebase/php-jwt
2.代码封装在lib文件中
<?php
namespace app\lib;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT as JWTUtil;
use think\Exception;
use think\response\Json;
class JWT
{
/**
* 根据json web token设置的规则生成token
* @return string|\think\response\Json
*/
public static function createjwt($user_id)
{
//jwt的签发密钥,验证token的时候需要用到
$key = md5('dd');
//签发时间
$time = time();
//过期时间
$expire = $time + 14400;
$token = array(
"user_id" => "$user_id",
//签发组织
"iss" => "http://www.najingquan.com/",//签发组织
"aud" => "zz", //签发作者
"iat" => $time,
"nbf" => $time,
"exp" => $expire
);
return JWTUtil::encode($token, $key);
}
/**
* 验证token
* @return \think\response\Json
* @throws Exception
*/
public static function verifyjwt($jwt)
{
//查看token是否过期(在退出登录的逻辑里会手动让其过期)
if (!empty(cache('delete_token')) && in_array($jwt, cache("delete_token"))) {
throw new ExpiredException("token过期", "400");
}
//jwt的签发密钥,验证token的时候需要用到
$key = md5('dd');
try {
$jwtAuth = json_encode(JWTUtil::decode($jwt, $key, array("HS256")));
$authInfo = json_decode($jwtAuth, true);
if (!$authInfo['user_id']) {
throw new Exception('用户ID不存在', '500');
}
//验签成功返回
return json($authInfo);
} catch (ExpiredException $e) {
throw new Exception('token过期', '500');
} catch (\Exception $e) {
throw new Exception($e->getMessage(), '500');
}
}
//从请求信息中获取token令牌
public static function getRequestToken()
{
if (empty($_SERVER['HTTP_AUTHORIZATION'])) {
return false;
}
$header = $_SERVER['HTTP_AUTHORIZATION'];
$method = 'bearer';
//去除token中可能存在的bearer标识
return trim(str_ireplace($method, '', $header));
}
}
3.修改public/.htaccess文件,通过apache重写,处理HTTP请求中的Authorization字段
(不处理,php中接收不到HTTP_AUTHORAZATION字段信息)
在.htaccess里面加多一项
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/?s=$1 [QSA,PT,L]
#增加下面这项
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
</IfModule>
4.取出、销毁
public function login(){
//取出Token值(寄托在header)
//清空token 将需清空的token存入缓存,再次使用时,会读取缓存进行判断
$token=JWT::getRequestToken();
//查看缓存中是否存在delete_token这个键
$delete_token = cache('delete_token') ?: [];
//将这个token值放入delete_token数组中
$delete_token[] = $token;
//将数组塞回缓存中
cache('delete_token', $delete_token, 86400);
//销毁成功
return success('销毁成功');
}