CodeIgniter 4自定义授权过滤器异常及控制器过滤配置问询
问题一:已登录时访问/user/changeEmail或/user/changePassword被重定向到/user/index的原因
从你提供的代码来看,UsersFiltersAuth过滤器本身只会在未登录(无$_SESSION['user_id'])时重定向到登录页,登录状态下应该会正常放行到目标控制器方法。出现这种意外重定向,大概率是以下两种情况:
全局过滤器配置冲突
检查你的app/Config/Filters.php文件,看看是否在$globals数组中全局启用了usersFiltersNoAuth过滤器。比如:public $globals = [ 'before' => [ 'usersFiltersNoAuth', // 如果全局加了这个,所有请求都会先执行它 // ...其他全局过滤器 ], // ... ];全局过滤器会在路由指定的过滤器之前执行,当你已登录(存在
user_id)时,全局的usersFiltersNoAuth会触发重定向到/user/index,这就覆盖了路由中usersFiltersAuth的逻辑。User控制器内部的重定向逻辑
检查User控制器的__construct方法或者changeEmail/changePassword方法本身,是否存在额外的登录状态判断并强制重定向到/user/index的代码。比如控制器构造函数里可能写了:public function __construct() { parent::__construct(); if (session()->has('user_id')) { return redirect()->to('/user/index'); } }这种情况下,即使过滤器放行,控制器自身也会触发重定向。
问题二:给整个控制器应用过滤器并排除部分方法
当然可以!CodeIgniter 4支持直接给控制器绑定过滤器,同时通过except或only参数精准控制哪些方法需要过滤(或排除过滤)。
实现方式一:路由配置绑定
用$routes->controller()方法给整个控制器添加过滤器,同时指定except参数排除不需要过滤的方法:
// 给User控制器整体应用usersFiltersAuth过滤器,排除login、registration方法 $routes->controller('/user', 'User', ['filter' => 'usersFiltersAuth', 'except' => ['login', 'registration']]); // 单独处理logout路由 $routes->add('/logout', 'User::logout');
也可以用only参数指定只对特定方法应用过滤器:
// 只给User控制器的changeEmail、changePassword方法应用usersFiltersAuth $routes->controller('/user', 'User', ['filter' => 'usersFiltersAuth', 'only' => ['changeEmail', 'changePassword']]);
实现方式二:控制器注解绑定
CodeIgniter 4支持用PHP注解给控制器或方法绑定过滤器,写法更直观:
<?php namespace App\Controllers; use CodeIgniter\Filters\Filters; // 给整个控制器应用usersFiltersAuth过滤器,排除login、registration方法 #[Filters('usersFiltersAuth', except: ['login', 'registration'])] class User extends BaseController { public function login() { // ...登录逻辑 } public function registration() { // ...注册逻辑 } public function changeEmail() { // ...修改邮箱逻辑 } // ...其他方法 }
注意:如果同时使用路由过滤器和控制器注解过滤器,路由的配置优先级更高。
内容的提问来源于stack exchange,提问作者pippuccio76

