怎么在thinkPHP5中使用Rabc实现权限管理
在实现一个完整的web应用时,我们通常需要一个完善的权限管理系统来保护敏感操作和数据,防止恶意攻击和误操作。其中的一个常用的解决方案就是使用Rbac(Role-based access control)模型。
在ThinkPHP5中,自带了Rbac的支持,本篇文章将介绍如何在ThinkPHP5中使用Rbac实现权限管理。
1. 数据库设计
为了实现Rbac模型,我们需要在数据库中建立多个表来存储角色、权限和用户等信息。下面是一个简单的示例表设计,实际情况下,你可能需要根据具体的业务需求来进行扩展。
角色表:
| id | name | description |
|----|--------|-------------|
| 1 | admin | 管理员 |
| 2 | member | 普通用户 |
权限表:
| id | name | description |
|----|-----------|-------------|
| 1 | add_user | 添加用户 |
| 2 | edit_user | 修改用户 |
角色权限关联表:
| id | role_id | permission_id |
|----|---------|--------------|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
用户表:
| id | username | password |
|----|----------|----------|
| 1 | admin | 123456 |
| 2 | user1 | 123456 |
用户角色关联表:
| id | user_id | role_id |
|----|---------|---------|
| 1 | 1 | 1 |
| 2 | 2 | 2 |
2. 配置文件
在使用Rbac之前,我们需要在配置文件中添加相应的设置。打开config文件夹下的auth.php文件,并按如下方式进行设置:
'auth' => [
'auth_on' => true, // 权限开关
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
'auth_group' => 'auth_role', // 角色表,不包含前缀
'auth_group_access' => 'auth_role_user', // 用户-角色关系表,不包含前缀
'auth_rule' => 'auth_permission', // 权限规则表,不包含前缀
'auth_user' => 'auth_user', // 用户信息表,不包含前缀
],
其中auth_on表示是否开启权限控制,auth_type表示认证方式,如果设置为1,则每次请求都会进行实时认证,如果设置为2,则只在用户登录时进行认证。
auth_group、auth_group_access、auth_rule、auth_user是我们自己定义的表名,这些表名可以根据实际情况进行修改。
3. 模型定义
接下来,我们需要定义相应的模型。打开app/common/model文件夹,在其中新建Role.php、Permission.php、User.php、UserRole.php四个模型。
其中Role代表角色,Permission代表权限,User代表用户,UserRole代表用户和角色的关系。
Role.php
<?php
namespace app\common\model;
use think\Model;
class Role extends Model
{
protected $table = 'auth_role';
public function permissions()
{
return $this->belongsToMany('Permission', 'auth_role_permission', 'role_id', 'permission_id');
}
public function users()
{
return $this->belongsToMany('User', 'auth_role_user', 'role_id', 'user_id');
}
}
Permission.php
<?php
namespace app\common\model;
use think\Model;
class Permission extends Model
{
protected $table = 'auth_permission';
public function roles()
{
return $this->belongsToMany('Role', 'auth_role_permission', 'permission_id', 'role_id');
}
}
User.php
<?php
namespace app\common\model;
use think\Model;
class User extends Model
{
protected $table = 'auth_user';
public function roles()
{
return $this->belongsToMany('Role', 'auth_role_user', 'user_id', 'role_id');
}
public function getRoles()
{
return $this->roles()->select();
}
public function can($permission)
{
$roles = $this->getRoles();
foreach ($roles as $role) {
if ($role->permissions()->where(['name' => $permission])->find()) {
return true;
}
}
return false;
}
}
UserRole.php
<?php
namespace app\common\model;
use think\Model;
class UserRole extends Model
{
protected $table = 'auth_role_user';
}
在上面的模型中,我们用到了belongsToMany()方法建立角色和权限/用户之间的多对多关系。另外,给User模型添加了一个can()方法,用于判断用户是否具有某个权限。
4. 中间件定义
我们可以使用中间件来对请求进行拦截和验证。打开app/middleware文件夹,在其中新建Auth.php中间件。
Auth.php
<?php
namespace app\middleware;
use think\facade\Session;
use app\common\model\User;
class Auth
{
public function handle($request, \Closure $next)
{
if (!Session::has('user')) {
return redirect('/login');
}
$user = User::get(Session::get('user')->id);
if (!$user || !$user->can(Request::module() . '/' . Request::controller() . '/' . Request::action())) {
return abort(403, '无权操作!');
}
$request->bind('user', $user);
return $next($request);
}
}
在这个中间件中,我们采用了对请求进行拦截的方式,如果用户未登录则跳转到登录页面,如果用户无权操作,则返回403错误。
同时,我们把当前用户绑定到$request对象中,这样我们就可以在控制器中直接使用$request->user来访问当前用户对象。
5. 配置路由
最后,我们需要对路由进行配置,以便使用中间件进行权限控制。打开app/route/route.php文件,并按如下方式进行配置:
use app\middleware\Auth;
Route::group('', function () {
Route::rule('user/add', 'user/add')->middleware(Auth::class);
Route::rule('user/edit', 'user/edit')->middleware(Auth::class);
Route::rule('user/delete', 'user/delete')->middleware(Auth::class);
})->middleware(Auth::class);
这里我们对/user/add、/user/edit、/user/delete三个路由都进行了权限控制,只有具有相应权限的用户才能访问这些路由。
到这里,我们已经完成了在ThinkPHP5中使用Rbac进行权限管理的全部内容。需要注意的是,这只是一个简单的示例,实际应用中仍需根据具体业务需求来进行进一步的扩展。
