56. 访问限制
简介
在本节里,我们将限制只有登录用户才可以修改个人信息。
需求
在本节里我们将限制只有登录用户才可以修改个人信息,这功能也是 产品分解 里用户和游客的一个不同之处。按照 产品分解 里的用例说明,在接下来几章里还有很多用例是只允许登录用户操作,所以我们在本节结束之前完成此功能也可以避免以后返工。
对于实现限制只有登录用户才可以访问这个功能,很多人第一反应是在控制器的 initialize
方法或在控制( action )方法 (action)逻辑代码之前判断登录用户是否存在。如果不存在就跳转到登录页面,否则继续执行方法。这也是之前 ThinkPHP 项目里经常使用的实现方式。
不过在本项目里,我们打算用 前置中间件 来实现这种访问限制。因为前置中间件是在控制器之前执行,这样消耗的系统资源也少。
另外,我们的后台模块也是使用 前置中间件 限制只有登录管理员可以访问后台。请对照 官方文档、 application/admin/config/middleware.php
和 route/admin.php
一起查看。
中间件
首先,我们用命令行工具创建限制登录用户访问的中间件- Auth
。需要注意的是, 创建中件间时不要指定模块名 ,这一点和创建数据模型或控制器不同,即使你指定了模块名生成的中间件也是存储在 `application/http/middleware' 目录。
$ php think make:middleware Auth
新建中间件代码如下:
application/http/middleware/Auth.php
<?php
namespace app\http\middleware;
use app\common\model\User;
class Auth
{
public function handle($request, \Closure $next)
{
if(empty(User::currentUser())){
if($request->isAjax()){
$result = [
'code' => 0,
'msg' => '请先登录系统',
'data' => [],
'url' => url('[page.login]'),
];
return json($result);
}else{
return redirect('[page.login]');
}
}
return $next($request);
}
}
代码解读
- '$this->error' 和 '$this->redirect' 方法是
think\Conroller
声明的方法,因为我们定义的所有控制器都直接或间接的继承于它,所以在控制器里可以调用这两个方法,而中间件类不是继承于think\Conroller
,所以在中间件里返回错误信息或跳转页面时不能使用这两个方法。
其次,在前台模块创建中间件配置文件,并完成注册。
index/config/middleware.php
<?php
return [
'auth' => [
\app\http\middleware\Auth::class,
],
];
控制器
最后,我们在控制器里使用中间件对控制( action )方法添加访问限制。
application/index/controller/User.php
<?php
.
.
.
class User extends Controller
{
protected $middleware = [
'auth' => ['except' => ['read']],
];
.
.
.
}
代码解读
- 在控制器里注册中间件时可以使用
except
和only
, 即也就是我们常说的 白名单 和 黑名单 ,在这里我建议大家在控制器里尽量用except
来注册中间件,这样可以确保我们新添加的控制( action )方法默认都是受中间件保护的。
如果有人看过
route/admin.php
文件的话,可能会好奇为什么我们在前台模块不同相同的方法在声明路由时 使用闭包定义中间件 ,而是在控制器里注册中间件。这样当项目控制器很多时,我们可能需要在每个控制器里重复注册中间件? 其实笔者最初也是想在声明路由时注册中间件,但因为把路由配置修改成以下内容时,中间件并没有起作用才选择在控制器里注册。
对于这是不是笔者所使用的 ThinkPHP 版本中的一个 bug ,笔者没有仔细研究,大家如果对这有兴趣的话可以探索一下。
效果展示
提交代码
下面把代码纳入到版本管理。
$ git add -A
$ git commit '使用中间件实现登录用户访问限制'
推荐文章: