php路由控制权限,Laravel 中使用路由控制权限(不限于 Laravel,只是一种思想)

Start

权限设计是后台管理很重要的一个功能,所以要好好设计。

PHP 已经有很多这方面的packages了,就不用我们重复造轮子了。当然,如果你愿意可以从头开始~

PS

以前做权限认证的方式有好几种,我说说常用的两种吧!

每一个页面认证当前需要的权限一次

在统一的地方(中间件)验证

先上一下简单的表结构(只保留重要的信息)数据库的模型 ER 图

f5129e345fc83e29d2a399e083360a31.png

(ps:这个设计中,用户不会直接拥有权限,只能通过角色继承权限。有很多packages会提供用户可以直接拥有权限功能)

Model

模型关联关系处理:

User 模型

namespace App\Models;

use Illuminate\Notifications\Notifiable;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable

{

use Notifiable;

/**

* The attributes that should be hidden for arrays.

*

* @var array

*/

protected $hidden = [

'password', 'remember_token',

];

// 用户和角色的模型关联关系

public function roles()

{

return $this->belongsToMany(Role::class);

}

/****************************************

* 封装一个方法方便使用

* 1. 需要的权限

* 2. 遍历当期那用户拥有的所有角色

* 3. 再通过角色判断是否有当前需要的权限

****************************************/

public function hasPermission($permissionName)

{

foreach ($this->roles as $role) {

if ($role->permisssions()->where('name', $permissionName)->exists()) {

return true;;

}

}

return false;

}

}

Role 模型

namespace App\Models;

class Role extends Model

{

// 用户和角色的模型关联关系

public function users()

{

return $this->belongsToMany(User::class);

}

// 角色和权限的模型关联关系

public function permissions()

{

return $this->belongsToMany(Permission::class);

}

}

Permission 模型

namespace App\Models;

class Role extends Model

{

// 角色和权限的模型关联关系

public function roles()

{

return $this->belongsToMany(Role::class);

}

}

Database Seed

插入一些记录:

########################################

# users:

+-------+---------+-----------+

| id | name | password |

+-----------------+-----------+

| 1 | gps | 123456 |

+-----------------+-----------+

| 2 | david | 123456 |

+-----------------+-----------+

########################################

# roles:

+-------+---------+

| id | name |

+-----------------+

| 1 | admin |

+-----------------+

########################################

# permissions:

+-------+-----------------+

| id | name |

+-------------------------+

| 1 | create_product |

| 2 | delete_product |

+-------------------------+

########################################

# role_user (用户 gps 拥有 admin 角色身份)

+---------+---------+

| role_id | user_id |

+---------+---------+

| 1 | 1 |

+------------------+

########################################

# permission_role (角色 admin 拥有创建商品和删除商品的权限)

+---------+---------------+

| role_id | permission_id |

+---------+---------------+

| 1 | 1 |

| 1 | 2 |

+-------------------------+

First

第一种大概介绍一下:

namespace App\Http\Controllers;

use App\Models\Product;

class ProductsController extends Controller

{

public function store(Request $request)

{

// 判断当前登录的用户是否有权限

if (! $request->user()->hasPermission('create_product')) {

abort(403);

}

// do something

return back()->with('status', '添加商品成功');

}

public function destroy(Product $product)

{

// 判断当前登录的用户是否有权限

if (! $request->user()->hasPermission('delete_product')) {

abort(403);

}

// do something

return back()->with('status', '删除商品成功');

}

}

Two

通过上面的代码我们可以看到,即使封装了权限验证的代码,还是要在不同的方法进行验证,而且可扩展性不高,这时候我们只需要在权限表加一个字段,就可以解决问题

1. permissions (加多一个 route 字段, 如果不在 laravel 中使用,可以加一个 url 字段匹配)

+-------+------------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+------------------+------+-----+---------+----------------+

| id | int(10) unsigned | NO | PRI | NULL | auto_increment |

| name | varchar(191) | NO | | NULL | |

| route | varchar(191) | NO | | NULL | |

+-------+------------------+------+-----+---------+----------------+

2. 这时候插入数据的时候,我们只要做好相关的录入

+-------+-----------------+------------------+

| id | name | route |

+-------------------------+------------------+

| 1 | create_product | products.store |

| 2 | delete_product | products.destroy |

+-------------------------+------------------+

添加好数据的时候,我们就不用再控制器里验证了,我们只需要新建一个中间件。

namespace App\Http\Middleware;

use Closure;

use Illuminate\Support\Facades\Route;

use App\Models\Permission;

class PermissionAuth

{

/**

* 把这个中间件放入路由组,把需要的验证的路由

* 放入这个中间组里

*/

public function handle($request, Closure $next)

{

/****************************************

* 获取当前路由的别名,如果没有返回 null

* (不在 laravel 中使用时,可以获取当前 url )

****************************************/

$route = Route::currentRouteName();

// 判断权限表中这条路由是否需要验证

if ($permission = Permission::where('route', $route)->first()) {

// 当前用户不拥有这个权限的名字

if (! auth()->user()->hasPermission($permission->name)) {

return response()->view('errors.403', ['status' => "权限不足,需要:{$permission->name}权限"]);

}

}

return $next($request);

}

}

END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值