【问题标题】:Laravel FormRequest validation gets User model and sometimes directly the nameLaravel FormRequest 验证获取用户模型,有时直接获取名称
【发布时间】:2020-11-13 15:19:47
【问题描述】:

我正在使用 Laravel 8 并使用 form request validation 验证我的请求。但是,我有一个奇怪的问题。在描述我的问题之前,我将在此处粘贴我的路线和验证类:

路线:

Route::post('users', ['as' => 'user.search', 'uses' => 'UserController@indexSearch']);

Route::post('user/name', ['as' => 'user.name.exists', 'uses' => 'UserController@nameExists']);

Route::post('user/email', ['as' => 'user.email.exists', 'uses' => 'UserController@emailExists']);

Route::post('user/email/check', ['as' => 'user.email.check', 'uses' => 'UserController@emailCheck']);

Route::get('user/{user:name}', ['as' => 'user.show', 'uses' => 'UserController@show']);

Route::get('user/{user:name}/einstellungen', ['as' => 'user.settings', 'uses' => 'UserController@showSettings']);

Route::get('user/{user:name}/produkte', ['as' => 'user.products', 'uses' => 'UserController@userProducts']);

Route::post('user/{user:name}/produkte', ['as' => 'user.products.post', 'uses' => 'UserController@userProducts']);

Route::get('user/{user:name}/saved/produkte', ['as' => 'user.marked.products', 'uses' => 'UserController@userMarkedProducts']);

Route::post('user/{user:name}/saved/produkte', ['as' => 'user.marked.products.post', 'uses' => 'UserController@userMarkedProducts']);

Route::post('user/{user:name}/avatar/upload', ['as' => 'user.avatar.update', 'uses' => 'UserController@update']);

Route::post('user/{user:name}/avatar/valid', ['as' => 'user.avatar.valid', 'uses' => 'UserController@validAvatar']);

Route::post('user/{user:name}/avatar/löschen', ['as' => 'user.avatar.delete', 'uses' => 'UserController@deleteAvatar']);

Route::post('user/{user:name}/update/password', ['as' => 'user.password.change', 'uses' => 'UserController@updatePassword']);

Route::post('user/{user:name}/validate/password', ['as' => 'user.password.validate', 'uses' => 'UserController@validatePassword']);

这是我的FormRequest 验证,它检查用户是否有权执行此请求以及给定数据是否有效。如您所见,我检查Auth::user()->name 是否与请求的用户($this->user->name)相同以更改图像。因为只有他的头像的所有者才能被允许更改是头像。

class UserAvatarUpdateRequest extends FormRequest
{
    public function authorize()
    {
        dump(array('auth' => Auth::user()->name, 'requested' => $this->user));     

        if(Auth::check() && Auth::user()->name == $this->user->name){
            return true;
        }

        return false;
    }
    
    public function rules()
    {
        return [
            'avatar' => [
                'required',
                'image',
                'max:5000',
                'mimes:jpeg,png,jpg',
                Rule::dimensions()->minWidth(200)->minHeight(200)->ratio(1)
            ],
        ];
    }

}

现在我来解决这个问题。如您所见,我有几条路线供我的用户使用,其中一条路线称为user.avatar.valid,另一条路线称为user.avatar.update

user.avatar.validuser.avatar.update 这两条路由都使用我在上面粘贴的 FormRequest 验证类。基本上user.avatar.valid 在用户提交表单以检查上传的图像是否有效之前被调用。我知道,我也可以在一个请求中执行此操作,但这是不可能的,因为我使用 vee-validate 让 Vuejs 验证表单是否有效。

但是,这不是这里的问题。问题是,当调用user.avatar.valid 路由时,我的转储回显了所请求用户的密钥requested name。但是,当执行对user.avatar.update 的请求时,我没有得到用户的name,而是用户object,其中包含idnameemail 等等。

但这正是重点...当尝试调用user.avatar.update 时,我收到403 错误(禁止),因为$this->user 不等于Auth::user()->name。显然,当我将 string(名称)与用户 object 进行比较时,情况就不一样了。

但是,当调用 user.avatar.valid 时,它通过了,因为这里我在调用 $this->user 时得到 name 而不是用户 object

但这是为什么呢?

当我将$this->user 更改为$this->user->name 时,我在调用user.avatar.update 路由时得到了用户的实际名称,但另一方面,在调用user.avatar.valid 路由时出现500 错误,因为它说Trying to get property 'name' of non-object...

有人知道问题出在哪里以及如何解决这个问题吗?

诚挚的问候,谢谢!

【问题讨论】:

  • 为什么这个标签是 Symfony?
  • 可以显示update()validAvatar()的参数吗?可能会触发Route Model Binding
  • 参数是指函数参数还是路由参数?另外,如果这有帮助:我现在已经拆分了这两个请求,但我面临同样的问题。我的验证和更新函数有自己的 FormRequest 文件,但我仍然有同样的错误......但由于拆分,实际上不再有任何触发......
  • 我不明白您为什么要进行这种手动验证。当用户通过身份验证时,他应该只能更新 Auth::user()->avatar(),所以只能更新自己的头像。另外,你为什么使用“name”而不是“ids”或“uuids”,这样可以防止字符或空格问题?您是否在这两种情况下都尝试过转储“^request->all()”以检查问题不是来自提交的 POST 数据?
  • user.avatar.valid 路由的控制器方法在哪里?你忘了在那个控制器方法中输入User $user 吗?

标签: php laravel validation laravel-formrequest


【解决方案1】:

确保您在控制器的方法签名中为路由模型绑定正确地键入了属性。如果没有,您将只获得段的值、用户的名称,而不是用户模型,因为不会发生隐式模型绑定:

public function validAvatar(User $user) { ... }

Laravel 8.x Docs - Routing - Route Model Bindings - Implicit Binding

【讨论】:

  • 对不起...我不知道你在说什么。您指的是文档的哪一部分?我应该把这个函数放在哪里?
  • 这是您对user.avatar.valid 方法的操作...只是根据您的路线显示您尝试使用的模型绑定的类型提示
  • 明白了。但是我必须在哪里放置 valid 函数?还是说这是我的function 来验证头像?
  • 那是你的路由控制器方法user.avatar.valid UserController@validAvatar ...我的名字打错了
猜你喜欢
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 2013-11-06
相关资源
最近更新 更多