权限设计是后台管理很重要的一个功能,因此要好好设计。 PHP 已经有不少这方面的packages了,就不用咱们重复造轮子了。固然,若是你愿意能够从头开始~php
之前作权限认证的方式有好几种,我说说经常使用的两种吧!laravel
packages
会提供用户能够直接拥有权限功能)模型关联关系处理:git
<?php 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; } }
<?php namespace App\Models; class Role extends Model { // 用户和角色的模型关联关系 public function users() { return $this->belongsToMany(User::class); } // 角色和权限的模型关联关系 public function permissions() { return $this->belongsToMany(Permission::class); } }
<?php namespace App\Models; class Role extends Model { // 角色和权限的模型关联关系 public function roles() { return $this->belongsToMany(Role::class); } }
######################################## # 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 | +-------------------------+
第一种大概介绍一下:github
<?php 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', '删除商品成功'); } }
经过上面的代码咱们能够看到,即便封装了权限验证的代码,仍是要在不一样的方法进行验证,并且可扩展性不高,这时候咱们只须要在权限表加一个字段,就能够解决问题数据库
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 | +-------------------------+------------------+
添加好数据的时候,咱们就不用再控制器里验证了,咱们只须要新建一个中间件。this
<?php 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); } }
若是是在 laravel 中使用,已经有轮子了,请使用 https://github.com/spatie/laravel-permissionurl