我正在尝试支持并实现 FormRequest 对象以进行验证。我已经成功地为我的所有模型设置了表单请求,除了用户模型。我收到以下错误Declaration of App\Http\Requests\UserUpdateRequest::user() should be compatible with Illuminate\Http\Request::user($guard = NULL)
。研究此错误似乎是我通过策略处理授权的方式存在问题。请注意,UserStoreRequest有效,但UserUpdateRequest返回错误。
用户存储请求
<?php
namespace App\Http\Requests;
use App\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
class UserStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// Authorize action - create-user
return Gate::allows('create', User::class);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:8|confirmed',
'markets' => 'required|array',
'roles' => 'required|array',
];
}
/**
* Save the user.
*
* @return \App\User
*/
public function save()
{
// Create the user
$user = new User($this->validated());
// Set the password
$user->password = Hash::make($this->validated()['password']);
$user->setRememberToken(Str::random(60));
// Save the user
$user->save();
// Set users markets
$user->markets()->sync($this->validated()['markets']);
// Update the users role if included in the request
if ($this->validated()['roles']) {
foreach ($this->validated()['roles'] as $role) {
$user->roles()->sync($role);
if ($user->hasRole('admin')) {
$user->markets()->sync(Market::all());
}
}
}
return $user;
}
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'name.required' => 'The name is required.',
'email.required' => 'The email is required.',
'email.unique' => 'The email must be unique.',
'password.required' => 'The password is required.',
'password.confirmed' => 'The passwords do not match.',
'password.min' => 'The password must be at least 8 characters.',
'markets.required' => 'A market is required.',
'roles.required' => 'A role is required.',
];
}
}
用户更新请求
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
class UserUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// Authorize action - update-user
return Gate::allows('update', $this->user);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
];
}
/**
* Get the user from the route.
*
* @return \App\User
*/
public function user()
{
return $this->route('user');
}
/**
* Save the email role.
*
* @return \App\Role
*/
public function save()
{
// Update the user
$this->user->update($this->validated());
// // Check to see if password is being updated
// if ($this->validated()['password']) {
// $this->user->password = Hash::make($this->validated()['password']);
// $this->user->setRememberToken(Str::random(60));
// }
// // Set users markets
// $this->user->markets()->sync($this->validated()['markets']);
// // Set users roles
// // // Update the users role if included in the request
// if ($this->validated()['roles']) {
// foreach ($this->validated()['roles'] as $role) {
// $this->user->roles()->sync($role);
// if ($this->user->hasRole('admin')) {
// $this->user->markets()->sync(Market::all());
// }
// }
// }
// // Save the user
// $this->user->save();
return $this->user;
}
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'name.required' => 'The name is required.',
'email.required' => 'The email is required.',
'email.unique' => 'The email must be unique.',
'markets.required' => 'A market is required.',
'roles.required' => 'A role is required.',
];
}
}
如您所见,我已经注释掉了 UpdateRequest 的大部分代码以进行故障排除。看来问题出在authorize()
方法上。下面是来自UserPolicy的代码
用户策略
/**
* Determine whether the user can create models.
*
* @param \App\User $user
*
* @return mixed
*/
public function create(User $user)
{
return $user->hasPermission('create-user');
}
/**
* Determine whether the user can update the model.
*
* @param \App\User $user
* @param \App\User $model
*
* @return mixed
*/
public function update(User $user, User $model)
{
return $user->hasPermission('update-user');
}
用户控制器
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\UserStoreRequest $request
*
* @return \Illuminate\Http\Response
*/
public function store(UserStoreRequest $request)
{
return redirect($request->save()->path());
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\UserUpdateRequest $request
* @param \App\User $user
*
* @return \Illuminate\Http\Response
*/
public function update(UserUpdateRequest $request, User $user)
{
return redirect($request->save()->path());
}
我正在为此系统使用基于权限的授权。用户有hasPermission()
方法来验证用户是否具有执行操作所需的权限。我担心我对这个设置感到困惑并且我没有正确验证。在尝试在 User 模型上实现它之前,一切都已经完成。
有权限()
/**
* Check to see if the model has a permission assigned.
*
* @param string $permission
*
* @return bool
*/
public function hasPermission($permission)
{
if (is_string($permission)) {
if (is_null(Permission::whereName($permission)->first())) {
return false;
} else {
return $this->hasRole(Permission::where('name', $permission)->first()->roles);
}
}
return $this->hasRole($permission->roles);
}
有角色()
/**
* Check to see if model has a role assigned.
*
* @param string $role
*
* @return bool
*/
public function hasRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return (bool) $role->intersect($this->roles)->count();
}
更新
我尝试重命名UserUpdateRequest中的user()
方法来解决覆盖Request用户的任何问题。这清除了上面列出的错误,但随后未经授权返回响应。登录的用户具有允许更新用户的权限。这在使用的方法中调用。我只是不确定它是在检查登录用户还是模型用户。frank()
authorize()
Gate::allows
我进一步调查发现,将方法更改为frank()
. 我越来越Call to a member function update() on null
。我应该从 frank 方法返回从路由中提取的用户,但它似乎返回 null。
更新了 UserUpdateRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
class UserUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// Authorize action - update-user
return Gate::allows('update', $this->frank);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
];
}
/**
* Get the user from the route.
*
* @return \App\User
*/
public function frank()
{
return $this->route('user');
}
/**
* Save the email role.
*
* @return \App\Role
*/
public function save()
{
// Update the user
$this->frank->update($this->validated());
// // Check to see if password is being updated
// if ($this->validated()['password']) {
// $this->user->password = Hash::make($this->validated()['password']);
// $this->user->setRememberToken(Str::random(60));
// }
// // Set users markets
// $this->user->markets()->sync($this->validated()['markets']);
// // Set users roles
// // // Update the users role if included in the request
// if ($this->validated()['roles']) {
// foreach ($this->validated()['roles'] as $role) {
// $this->user->roles()->sync($role);
// if ($this->user->hasRole('admin')) {
// $this->user->markets()->sync(Market::all());
// }
// }
// }
// // Save the user
// $this->user->save();
return $this->frank;
}
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'name.required' => 'The name is required.',
'email.required' => 'The email is required.',
'email.unique' => 'The email must be unique.',
'markets.required' => 'A market is required.',
'roles.required' => 'A role is required.',
];
}
}