我们说我有一种检查用户是否是管理员的方法:
public function isAdmin()
{
return Auth::user()->role === 'admin';
}
然后我将它附加到路由过滤器:
Route::filter('admin', function($route, $request)
{
if ( ! Auth::user()->isAdmin()) {
Notification::error('No permission to view this page!');
return Redirect::back();
}
});
现在,我只是将它传递给路线组
Route::group(array('before' => 'admin'), function()
{
Route::post('users/{id}/update_password', 'UserController@update_password');
Route::post('users/{id}/delete', 'UserController@force_delete');
Route::delete('users/{id}', array('as' => 'users.destroy', 'uses' => 'UserController@destroy'));
Route::post('users/{id}/restore', 'UserController@restore');
Route::get('users/create', array('as' => 'users.create', 'uses' => 'UserController@create'));
Route::post('users', array('as' => 'users.store', 'uses' => 'UserController@store'));
Route::get('users/{id}/edit', array('as' => 'users.edit', 'uses' => 'UserController@edit'));
Route::put('users/{id}', array('as' => 'users.update', 'uses' => 'UserController@update'));
});
这里的问题是如何允许用户绕过此过滤器,例如他试图更新它自己的个人资料页面显然是他的不是和管理员? 我只想阻止对非管理员的用户路由的所有访问,但允许用户在他自己的个人资料上编辑/更新等,但允许管理员也这样做。
你能指点我正确的方向吗?
答案 0 :(得分:3)
您可以在过滤器中查看相关的请求段:
Route::filter('admin', function($route, $request)
{
if ( ! Auth::user()->isAdmin() && Auth::user()->username !== Request::segment(2)) {
Notification::error('No permission to view this page!');
return Redirect::back();
}
});
答案 1 :(得分:2)
有几种方法可以做到这一点,但是有一个过滤器可以检查当前经过身份验证的用户的请求段,这不是最好的方法。
选择编号1
您只需检查用户是否已获得身份验证(使用auth
过滤器),然后在控制器中检查用户是否为管理员,和/或是否为管理员。他们的个人资料。
选择编号2
专门为修改自己个人资料的用户定义辅助路线组,但不遵循/user/{id}/*
模式。
Route::group(['before' => 'admin'], function() {
// admin routes here
}
Route::group(['prefix' => '/me'], function() {
Route::post('/update_password', 'UserController@update_password');
Route::post('/delete', 'UserController@force_delete');
// etc
}
这意味着要编辑自己的个人资料,他们只需转到/me/edit
而不是/user/{id}/edit
。为了避免重复相同代码或错误因为缺少参数等问题,您可以在控制器中执行类似的操作。
private function getUserOrMe($id)
{
return $id !== false ? User::find($id) : Auth::user();
}
public function edit($id = false)
{
$user = $this->getUserOrMe($id);
}
我最近将这种特殊方法用于API。当然,它需要再次定义路线,但是假设您已经使用prefix
选项进行了设置,那么它就是一个复制和粘贴作业,另外,还有一些路由管理员会有一个用户不会。
无论哪种方式,过滤器都不打算做复杂的逻辑,而是提供一定程度的基本逻辑和路由保护。识别当前uri是否是当前登录用户的逻辑的逻辑是在控制器中更好地处理的。