本文的示例代码参考laravel-permission-demo
目录
Startup
docker run --name laravel-permission-demo -p 3306:3306 -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.7.17
docker exec -i laravel-permission-demo mysql -uroot -psecret <<< "CREATE DATABASE IF NOT EXISTS homestead DEFAULT CHARSET utf8 COLLATE utf8_general_ci;"
composer create-project laravel/laravel laravel-permission-demo && cd laravel-permission-demo
sed -i "" "s/DB_USERNAME=homestead/DB_USERNAME=root/g" .env
php artisan make:auth
php artisan migrate
php artisan route:list
laravel-permission
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
php artisan migrate
php artisan make:migration seed_roles_and_permissions_data
database/migrations/*seed_roles_and_permissions_data.php
<?php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Migrations\Migration;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class SeedRolesAndPermissionsData extends Migration
{
public function up()
{
app()['cache']->forget('spatie.permission.cache');
Permission::create(['name' => 'fetch_machines']);
Permission::create(['name' => 'create_machines']);
$projectManager = Role::create(['name' => 'project_manager']);
$projectManager->givePermissionTo('fetch_machines');
$projectManager->givePermissionTo('create_machines');
$driver = Role::create(['name' => 'driver']);
$driver->givePermissionTo('fetch_machines');
}
public function down()
{
app()['cache']->forget('spatie.permission.cache');
$tableNames = config('permission.table_names');
Model::unguard();
DB::table($tableNames['role_has_permissions'])->delete();
DB::table($tableNames['model_has_roles'])->delete();
DB::table($tableNames['model_has_permissions'])->delete();
DB::table($tableNames['roles'])->delete();
DB::table($tableNames['permissions'])->delete();
Model::reguard();
}
}
php artisan make:seed UsersTableSeeder
vim database/seeds/UsersTableSeeder.php
<?php
use App\User;
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
public function run()
{
$users = factory(User::class)
->times(2)
->make()
->each(function ($user, $index) {
if ($index === 0) {
$user->name = 'test1';
$user->email = 'test1@126.com';
} else if ($index === 1) {
$user->name = 'test2';
$user->email = 'test2@126.com';
}
});
$user_array = $users->makeVisible(['password', 'remember_token'])->toArray();
User::insert($user_array);
$user = User::find(1);
$user->assignRole('project_manager');
$user = User::find(2);
$user->assignRole('driver');
}
}
vim database/seeds/DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UsersTableSeeder::class);
}
}
vim app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
}
php artisan migrate:refresh --seed
Model
php artisan make:model Models/Machine --migration
vim app/Models/Machine.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Machine extends Model
{
protected $fillable = ['name', 'project_manager_id', 'driver_id'];
}
vim database/migrations/*create_machines_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMachinesTable extends Migration
{
public function up()
{
Schema::create('machines', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->unsignedInteger('project_manager_id');
$table->unsignedInteger('driver_id');
$table->timestamps();
$table->foreign('project_manager_id')
->references('id')
->on('users');
$table->foreign('driver_id')
->references('id')
->on('users');
});
}
public function down()
{
Schema::dropIfExists('machines');
}
}
php artisan migrate
php artisan make:seed MachinesTableSeeder
vim database/seeds/MachinesTableSeeder.php
<?php
use App\Models\Machine;
use Illuminate\Database\Seeder;
class MachinesTableSeeder extends Seeder
{
public function run()
{
$machine = new Machine();
$machine->name = 'machine1';
$machine->project_manager_id = '1';
$machine->driver_id = '1';
$machine->save();
$machine = new Machine();
$machine->name = 'machine2';
$machine->project_manager_id = '1';
$machine->driver_id = '2';
$machine->save();
}
}
vim database/seeds/DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(MachinesTableSeeder::class);
}
}
php artisan migrate:refresh --seed
Route
vim routes/web.php
<?php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::get('/machines', 'MachinesController@index')->name('machines_list');
Route::get('/machines/create', 'MachinesController@create')->name('machines_create');
php artisan make:controller MachinesController
vim app/Http/Controllers/MachinesController.php
<?php
namespace App\Http\Controllers;
class MachinesController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return 'machines_list';
}
public function create()
{
return 'machines_create';
}
}
php artisan serve
- 浏览器打开http://localhost:8000/login 登录如下账号
email: test1@126.com
password: secret
- 浏览器打开http://localhost:8000/machines 返回信息如下
machines_list
- 浏览器打开http://localhost:8000/machines/create 返回信息如下
machines_create
Middleware
vim app/Http/Kernel.php
protected $routeMiddleware = [
// ...
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
];
vim routes/web.php
<?php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::middleware(['permission:fetch_machines'])->group(function () {
Route::get('/machines', 'MachinesController@index')->name('machines_list');
});
Route::middleware(['permission:create_machines'])->group(function () {
Route::get('/machines/create', 'MachinesController@create')->name('machines_create');
});
php artisan serve
- 浏览器打开http://localhost:8000/login 登录如下账号
email: test1@126.com
password: secret
- 浏览器打开http://localhost:8000/machines 返回信息如下
machines_list
- 浏览器打开http://localhost:8000/machines/create 返回信息如下
machines_create
浏览器打开http://localhost:8000/home 退出当前登录账号test1
- 浏览器打开http://localhost:8000/login 登录如下账号
email: test2@126.com
password: secret
- 浏览器打开http://localhost:8000/machines 返回信息如下
machines_list
- 浏览器打开http://localhost:8000/machines/create 返回信息如下
Spatie \ Permission \ Exceptions \ UnauthorizedException
User does not have the right permissions.
Exception
vim app/Exceptions/Handler.php
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Spatie\Permission\Exceptions\UnauthorizedException;
class Handler extends ExceptionHandler
{
protected $dontReport = [
//
];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
if ($exception instanceof UnauthorizedException) {
return response()->json(['message' => 'Unauthenticated'], 401);
}
return parent::render($request, $exception);
}
}
- 浏览器打开http://localhost:8000/machines/create 返回信息如下
{ message: "Unauthenticated" }
Scope
vim app/Models/RoleScope.php
<?php
namespace App\Models;
use Auth;
trait RoleScope
{
public function scopeRole($query)
{
$user = Auth::user();
if (!$user->roles || !$user->roles->count()) {
return $query;
}
return $query->where($user->roles[0]->name . '_id', $user->id);
}
}
vim app/Models/Machine.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Machine extends Model
{
use RoleScope;
protected $fillable = ['name', 'project_manager_id', 'driver_id'];
}
vim app/Http/Controllers/MachinesController.php
<?php
namespace App\Http\Controllers;
use App\Models\Machine;
class MachinesController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return Machine::role()->get();
}
public function create()
{
return 'machines_create';
}
}
php artisan serve
- 浏览器打开http://localhost:8000/login 登录如下账号
email: test1@126.com
password: secret
- 浏览器打开http://localhost:8000/machines 返回信息如下
[
{
"id": 1,
"name": "machine1",
"project_manager_id": 1,
"driver_id": 1,
"created_at": "2018-07-24 02:22:38",
"updated_at": "2018-07-24 02:22:38"
},
{
"id": 2,
"name": "machine2",
"project_manager_id": 1,
"driver_id": 2,
"created_at": "2018-07-24 02:22:38",
"updated_at": "2018-07-24 02:22:38"
}
]
浏览器打开http://localhost:8000/home 退出当前登录账号test1
- 浏览器打开http://localhost:8000/login 登录如下账号
email: test2@126.com
password: secret
- 浏览器打开http://localhost:8000/machines 返回信息如下
[
{
"id": 2,
"name": "machine2",
"project_manager_id": 1,
"driver_id": 2,
"created_at": "2018-07-24 02:22:38",
"updated_at": "2018-07-24 02:22:38"
}
]