这篇文章主要转载于http://www.zhoujiping.com/new-in-laravel-5/gate.html
先做些准备工作, 先建立一个posts
的migration文件并运营migrate, 内容如下:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
到ModelFactory.php写上我们需要的测试数据:
$factory->define(App\Post::class, function (Faker\Generator $faker) {
return [
'user_id' => factory(App\User::class)->create()->id,
'title' => $faker->sentence,
'body' => $faker->paragraph
];
});
打开php artisan tinker, 生成一个posts表的测试数据
Psy Shell v0.8.0 (PHP 7.0.12 — cli) by Justin Hileman
>>> factory(App\Post::class)->create();
=> App\Post {#695
user_id: 1,
title: "Qui adipisci laboriosam qui mollitia quia.",
body: "Iusto omnis libero fuga quibusdam. Cum id id libero et necessitatibus ea. Officiis laboriosam occaecati aut.",
updated_at: "2016-12-24 06:01:31",
created_at: "2016-12-24 06:01:31",
id: 1,
}
>>> App\User::first();
=> App\User {#702
id: "1",
name: "Ms. Emelia Dooley",
email: "[email protected]",
created_at: "2016-12-24 06:01:31",
updated_at: "2016-12-24 06:01:31",
}
>>>
我们生成了posts的一条记录,同时也生成了对应的User。我们再去生成一个PostsController.php的控制器
php artisan make:controller PostsController
写个资源路由:
Route::resource('posts', 'PostsController');
我们在控制器中写一个显示某个具体帖子的方法show($id)
class PostsController extends Controller
{
public function show($id)
{
$post = Post::findOrFail($id);
return $post->title;
}
}
浏览器访问: http://localhost:8000/posts/1
针对这个问题,laravel给了我们提供了Gates和Policies两种方案,我们先来看第一种Gates怎么用(以后我们可以看下laravel是怎么实现这个功能的)要使用Gate, 那我们首先需要去定义(注册)一个Gate,涉及到与注册相关的概念,我们肯定会想到服务提供者Provider, 到app/Providers/AuthServiceProvider.php中,将我们需要的Gate定义在boot()方法中,为什么要放这里,前面的文章已经讲解的非常清楚了。
public function boot()
{
$this->registerPolicies();
// 这里的$user是当前登录用户,laravel会处理
// 在调用的时候不用传入
Gate::define('show-post', function ($user, $post)) {
return $user->id == $post->user_id;
}
}
上面代码优化下,方便复用
public function boot()
{
$this->registerPolicies();
// 这里的$user是当前登录用户,laravel会处理
// 在调用的时候不用传入
Gate::define('show-post', function ($user, $post)) {
return $user->owns($post);
}
}
/** 在User.php中 */
public function owns($related)
{
return $this->id == $related->user_id;
}
定义好后,就能按下面这样调用了
public function show($id)
{
auth()->loginUsingId(1);
$post = Post::findOrFail($id);
if (Gate::denies('show-post', $post)) {
abort(403, 'Sorry, not sorrry.');
}
return $post->title;
}
本节都这里结束.