1、中间件是什么
- 中间件主要用于拦截或过滤应用的HTTP请求,并进行必要的业务处理。
- 可以看成是 数据访问过程中的拦截器 。比如可以在控制器处理之前,先验证token是否过期,是否正确等
2、创建中间件
php think make:middleware CheckToken
<?php
declare (strict_types = 1);
namespace app\middleware;
use app\warmtips\Result\Result; //统一返回处理
class CheckToken
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
//
// var_dump('中间件CheckToken');
// return $next($request);
// 获取token
$token = $request->param('token');
// 验证token是否存在
if(empty($token)){
return Result::Error(0,'token不能为空');
}else{
$res = checkToken($token);
if($res['code'] != 1){
return Result::Error($res['code'],$res['msg']);
}
}
return $next($request);
}
}
3、注册全局中间件
return [
// 注册中间件(验证token)
\app\middleware\CheckToken::class
];
4、注册应用中间件
- 在app下某个应用如admin中的middleware.php中注册
<?php
// 这是系统自动生成的middleware定义文件
return [
\app\middleware\Test::class
];
5、注册控制器中间件
protected $middleware = [\app\middleware\CheckToken::class => ['except' => ['login','index']]];
- 访问该控制器的所有方法都会先执行这个中间件
- except是跳过中间件,如上面的是login和index方法不用进行中间件验证
6、注册路由中间件
Route::get('hello/:name', 'index/hello')->middleware(\app\middleware\CheckToken::class);
7、中间件所写的验证方法一般都是写在公共文件
/**
* 生成token
* $uid 输入用户openid&&id
*/
if(!function_exists('signToken')){
// 生成验签
function signToken($uid)
{
$key = '!@#$%*&'; //这里是自定义的一个随机字串,应该写在config文件中的,解密时也会用,相当 于加密中常用的 盐 salt
$token = array(
"iss" => '', //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time(), //在什么时候jwt开始生效 (这里表示生成60秒后才生效)
"exp" => time() + 120, //token 过期时间 (这里表示过期时间为120秒)
'data' => $uid //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
);
$jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token
return $jwt;
}
}
/**
* 验证token
* $token 生成的token值
*/
if(!function_exists('checkToken')){
// 验证token
function checkToken($token)
{
$key = '!@#$%*&';
$status = array("code"=>2);
try {
// JWT::$leeway = 60; //当前时间减去60,把时间留点余地
JWT::$leeway = 0;
$decode = JWT::decode($token,new Key($key,'HS256')); //HS256方式,这里要和签发的时候对应
$arr = (array)$decode;
$res['code'] = 1;
$res['data'] = $arr['data'];
return $res;
} catch (SignatureInvalidException $e) { //签名不正确
$status['msg'] = "签名不正确";
return $status;
} catch (BeforeValidException $e) { // 签名在某个时间点之后才能用
$status['msg'] = "token未生效";
return $status;
} catch (ExpiredException $e) { // token过期
$status['msg'] = "token失效";
return $status;
} catch (Exception $e) { //其他错误
$status['msg'] = "未知错误";
return $status;
}
}
}
/**
* 检验当前登录用户id,以便验证接口权限
*/
if(!function_exists(uidGet)){
function uidGet($token){
$key = '!@#$%*&';
JWT::$leeway = 0;
$decode = JWT::decode($token,new Key($key,'HS256')); //HS256方式,这里要和签发的时候对应
$arr = (array)$decode;
return $arr['data'];
}
}
8、中间件的别名
- 在config下的middleware.php文件中配置
<?php
// 中间件配置
return [
// 别名或分组 (对于经常要使用的中间件定义一个别名)
'alias' => [
'CheckToken' => \app\middleware\CheckToken::class,
'Auth' => \app\middleware\Auth::class
],
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
'priority' => [],
];
protected $middleware = ['CheckToken' => ['except' => ['login','index']]];