1

我正在尝试支持并实现 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.',
        ];
    }
}
4

1 回答 1

3

问题是user()您在UserUpdateRequest课堂上定义的方法。

UserUpdateRequestextends Illuminate\Foundation\Http\FormRequest,而后者又延伸Illuminate\Http\RequestIlluminate\Http\Request已经user()定义了一个方法,因此user()您的UserUpdateRequest类中的方法正在尝试覆盖此定义。

由于您的UserUpdateRequest::user()方法与签名不匹配Illuminate\Http\Request::user($guard = null),因此您会收到该错误。

您可以:

  1. 从您的课程中删除该user()方法UserUpdateRequest,或
  2. 在您的班级重命名您的user()方法UserUpdateRequest,或
  3. $guard = null参数添加到类的user()方法中UserUpdateRequest,使其与基user()方法的签名相匹配。
于 2019-12-12T23:35:51.077 回答