作用
ThinkPHP 的中间件(Middleware),主要用于处理和管理 HTTP 请求和响应。中间件可以在请求进入应用程序之前或在响应离开应用程序之前进行操作,起到拦截和过滤的作用。
定义Middleware
在app下新建一个middleware文件夹,然后定义一个CheckAuth.php中间件文件
<?php
namespace app\middleware;
class CheckAuth
{
public function handle($request, \Closure $next)
{
// 检查请求的路由
$route = $request->url();
// dump($route);
// 只有特定的路由需要进行身份验证
$protectedRoutes = [
'/admin/index',
'/admin/index1',
// ... 其他受保护的路由
];
// 如果当前路由不在受保护的路由列表中,直接跳过身份验证
if (!in_array($route, $protectedRoutes)) {
return $next($request);
}
// 检查请求中是否包含 token
$token = $request->header('Authorization');
//假设token已经存在
$token = true;
if (empty($token)) {
// 如果 token 不存在,返回错误信息
return json(['message' => 'Token不存在'], 401);
}
// 在这里添加验证 token 的逻辑,例如查询数据库等
// 假设token验证通过,返回 true;否则返回 false
$isTokenValid = true;
if (!$isTokenValid) {
// 如果 token 无效,返回错误信息
return json(['message' => 'token无效'], 401);
}
// 如果 token 有效,允许请求通过
return $next($request);
}
}
注册中间件
这里我直接把CheckAuth在middleware.php注册成一个全局的中间件,所有请求都要经过这个中间件
如果要定义局部中间件,直接在路由中注册即可
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
\app\middleware\CheckAuth::class, //全局中间件,不需要再路由中定义
];
定义方法
在admin控制器中定义了三个方法,其中两个index方法要经过中间件,但是我们在中间件中已经设置了把token设置为true,判断token也设置为true,所有我们访问两个index方法是可以拿到返回值的,由于我们在中间件中定义了只有特定的路由才需要走中间件进行身份判定,login不包含在内,不管怎么折腾login都不受影响
<?php
namespace app\controller;
use app\BaseController;
use app\model\User;
class Admin extends BaseController{
public function login(){
$User = new User(); //实例化user类
$res = json_encode($User->getxUser()); //将返回结果转为json类型
return $res;
}
public function index(){
return json(["message"=>"这是经过中间件的方法"]);
}
public function index1(){
return json(["message"=>"也是经过中间件的方法"]);
}
}
按照上面的代码,我们去请求index,index1,login方法都没有问题
但是我们修改一下中间件的内容
在CheckAuth.php中把$token = true;去掉
此时我们再来请求index和index1,都显示Token不存在
但是我们访问login方法还是一点不变,还是可以得到数据
全局中间件大概就是这样
在路由中注册局部中间件
先定义一个中间件文件
<?php
namespace app\middleware;
class MyMiddleware
{
public function handle($request, \Closure $next)
{
$token = $request->header('Authorization');
//假设token已经存在
$token = true;
if (empty($token)) {
// 如果 token 不存在,返回错误信息
return json(['message' => 'Token不存在'], 401);
}
// 在这里添加验证 token 的逻辑,例如查询数据库等
// 假设token验证通过,返回 true;否则返回 false
$isTokenValid = true;
if (!$isTokenValid) {
// 如果 token 无效,返回错误信息
return json(['message' => 'token无效'], 401);
}
// 如果 token 有效,允许请求通过
return $next($request);
}
}
在路由中注册中间,router/app.php
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
use think\facade\Route;
Route::get('think', function () {
return 'hello,ThinkPHP6!';
});
Route::get('hello/:name', 'index/hello');
Route::rule('admin/login','/app/controller/Admin/login')->middleware(\app\middleware\MyMiddleware::class);
在这个例子中,我们使用了 GET 或 POST 方法定义了一个路由,当访问 admin/login 时将执行 app\controller\Admin 控制器的 login 方法,这个路由定义还指定了一个中间件\app\middleware\MyMiddleware::class,它将被应用于该路由。
现在我们去访问admin/login可以正常拿到数据
但是我们把$isTokenValid = false;就是验证token失败
至于前置中间件,后置中间件等其他的就自行看官方文档吧!
地址: https://www.kancloud.cn/manual/thinkphp6_0/1037493