目前有三种处理方式:1是每个操作之前判断,2是基类统一判断(目前九思项目使用),3是中间件统一判断(AOP)
首先说下第二种基类统一判断,如TP6中ba
第一种可以对所有操作进行拦截,也可灵活的决定放弃某此操作的拦截,但对于大型项目来说,往往不需要验证就是登录的操作了,其它的操作都要验证,若是需要更改验证或遗漏则会带来不可估计的后果。此时AOP思想的中间件就显得非常适合这种操作。
<?php
declare(strict_types=1);
namespace app\index\middleware;
class Base
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
/**
* 判断用户是否登录三种方式:1路由中间件,2继承父级方法中判断,3每个方法中判断
* 第一种和第二种都可对每个请求进行验证,不过后者要每个添加,不符合AOP思想
* 第二种方法是我目前网站上使用的,但测试登录后若删除session则不能判断,最终选择是中间件
* 中间件要完成对所有需要验证身份的操作进行拦截检查,除个别如登录操作,所以符合AOP思想,采用全局的拦截。可选全局中间件,应用中间件和路中间件全局模式
* 开始想到是应用中间件,但在应用中间中是无法通过$request->controller和$request->action获取控制器与方法,无法排除如登录页面或其它不需要验证的地方
* 在TP6社区中回答是应用前置中间件不支持获取控制器和方法,后置应用中间件可以,为防止用户操作被提前执行,测试了后置应用中间件,发现用户操作仍然是在中间件后面执行!
* 后来采用路由中间件全局模式,无论前置后置都能拦截判断!!!是最为推荐的方式
* 后来再想全局中间件的获取不了控制器方法也可采用类似于应用中间件方法解决,经测试有效
*/
// 每一种:后置全局/应用中间件(前置全局/应用中间件无法获取)
// $response = $next($request);
// $controller = $request->controller();
// $action = $request->action();
// $app = app('http')->getName();
// if (strtolower($controller) != "login" && empty(session('index'))) {
// return redirect('/login');
// }
// return $response;
//第二种:路由中间件(前置后置都符合要求)
$controller = $request->controller();
// $action = $request->action();
// $app = app('http')->getName();
if (strtolower($controller) != "login" && empty(session('index'))) {
return redirect('/login');
}
return $next($request);
}
}
现在就剩下中间件类型的选择了,TP6提供了全局中间件、应用中间件(多应用模式下有效)、路由中间件以及控制器中间件四个组。执行顺序分别为:全局中间件->应用中间件->路由中间件->控制器中间件
正如上面代码中注释所描述,为实现全局拦截的目的可选全局中间件,应用中间件和路由中间件全局模式,便经过测试全局中间件和应用中间件要获取控制器和方法,必须是后置中间件,若是前置中间件则为空,不能排除登录操作若其它指定操作,最后推荐是路由中间件,无论前置或后置均可以验证用户合法性。
全局中间件或应用中间件在对应目录下的middleware.php中加入`\app\index\middleware\ba
**路由中间件**因为要全局模式,需要在config\route.php配置文件中增加如下:
"middleware" => [
\app\index\middleware\Base::class,
]
现在登录验证或用户身份合法性检测基本就是上面思路了,研究中间件时还发现了TP6提供了Laravel表单验证的方法,就是新增加的内置FormTokenCheck中间件,只要在路由最后添加token方法即可 最佳答案
