介绍
Laravel 表单请求是扩展常规请求类功能的特殊类,允许 高级验证功能. 表单请求还有助于保持控制器操作更清洁,因为您可以将所有验证逻辑移动到表单请求类别。
在本指南中,我们将实施密码验证步骤,要求用户在访问管理员区域之前确认其密码。
前提条件
要遵循本指南,您需要一个运行Laravel 5.6+应用程序,其中包含内置的Laravel身份验证设置,请查看官方文档(https://laravel.com/docs/5.6/authentication)以了解如何设置此功能的详细信息。
步骤1 - 创建观点
我们将通过设置用户编辑个人资料页面开始。
在撰写本教程时,手工
命令实用程序不会生成视图,因此我们需要手动创建视图。
创建文件 resources/views/profile/edit.blade.php
并添加以下代码。
1@extends('layouts.app')
2
3@section('content')
4<div class="container">
5 @if (session('info'))
6 <div class="row">
7 <div class="col-md-12">
8 <div class="alert alert-success alert-dismissible">
9 <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
10 {{ session('info') }}
11 </div>
12 </div>
13 </div>
14 @elseif (session('error'))
15 <div class="row">
16 <div class="col-md-12">
17 <div class="alert alert-danger alert-dismissible">
18 <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
19 {{ session('error') }}
20 </div>
21 </div>
22 </div>
23 @endif
24 <div class="row">
25 <div class="col-md-8 col-md-offset-2">
26 <div class="panel panel-default">
27 <div class="panel-heading">Update Profile</div>
28
29 <div class="panel-body">
30 <form class="form-horizontal" method="POST" action="{{ route('profile.update', ['user' => $user]) }}">
31 {{ csrf_field() }}
32 {{ method_field('PUT') }}
33 <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
34 <label for="name" class="col-md-4 control-label">Name</label>
35 <div class="col-md-6">
36 <input id="name" type="text" class="form-control" name="name" value="{{ $user->name }}">
37
38 @if ($errors->has('name'))
39 <span class="help-block">
40 <strong>{{ $errors->first('name') }}</strong>
41 </span>
42 @endif
43 </div>
44 </div>
45
46 <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
47 <label for="password" class="col-md-4 control-label">Password</label>
48
49 <div class="col-md-6">
50 <input id="password" type="password" class="form-control" name="password">
51
52 @if ($errors->has('password'))
53 <span class="help-block">
54 <strong>{{ $errors->first('password') }}</strong>
55 </span>
56 @endif
57 </div>
58 </div>
59
60 <div class="form-group">
61 <label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
62
63 <div class="col-md-6">
64 <input id="password-confirm" type="password" class="form-control" name="password_confirmation">
65 </div>
66 </div>
67
68 <div class="form-group{{ $errors->has('current_password') ? ' has-error' : '' }}">
69 <label for="current-password" class="col-md-4 control-label">Current Password</label>
70
71 <div class="col-md-6">
72 <input id="current-password" type="password" class="form-control" name="current_password">
73
74 @if ($errors->has('current_password'))
75 <span class="help-block">
76 <strong>{{ $errors->first('current_password') }}</strong>
77 </span>
78 @endif
79 </div>
80 </div>
81
82 <div class="form-group">
83 <div class="col-md-6 col-md-offset-4">
84 <button type="submit" class="btn btn-primary">
85 Update
86 </button>
87 </div>
88 </div>
89 </form>
90 </div>
91 </div>
92 </div>
93 </div>
94</div>
95@endsection
在我们的编辑个人资料
页面上,我们检查一个信息
和错误
闪存消息,并向用户显示它。
它有名称
,密码
,password_confirmation
和current_password
字段。
我们希望它工作的方式是,每当用户做出更改时,他们必须提供正确的current_password
字段,以便将更新交付到数据库中。
密码
和密码_确认
字段将允许用户更改他们的密码.如果它们都空,用户的当前密码将被保留,不会对其存储的密码进行更改。
在我们看来,主要参与者是密码
,password_confirmation
和current_password
字段。
至于名称
字段,它作为一个例子来扩展并为您的案例添加更多字段。
步骤 2 – 创建表格请求
现在,我们来谈谈本教程中最重要的部分。
执行以下命令创建表单请求。
1php artisan make:request UpdateProfile
上面的命令将创建一个名为app/Http/Requests/UpdateProfile.php
的文件。
本节中的所有代码更改都将对此文件进行。
我们需要做的第一件事是名称(Laravel的哈希面孔)(LINK0)类声明之前。
1use Illuminate\Support\Facades\Hash;
接下来,我们需要从我们的授权
方法返回真实
,因为我们在表单请求中没有执行授权。
1/**
2 * Determine if the user is authorized to make this request.
3 *
4 * @return bool
5 */
6public function authorize()
7{
8 return true;
9}
我们的规则方法将返回描述此请求的验证规则的数组。
1/**
2 * Get the validation rules that apply to the request.
3 *
4 * @return array
5 */
6public function rules()
7{
8 return [
9 'name' => 'required|string|max:255',
10 'password' => 'nullable|required_with:password_confirmation|string|confirmed',
11 'current_password' => 'required',
12 ];
13}
名称
和当前密码
的规则是自我解释的。
密码
规则规定,使用确认
声明来确认密码。
它还声明‘required_with:password_confirmation’,这意味着如果用户提供密码确认,他们也应该提供密码。
这些验证规则将在我们在控制器操作中输入提示后自动检查每个请求(我们将在稍后进行)。
我们需要做的最后一件事是根据我们的要求声明一个与验证器
的方法,在任何验证规则之前通过完全构建的验证器实例。
1/**
2 * Configure the validator instance.
3 *
4 * @param \Illuminate\Validation\Validator $validator
5 * @return void
6 */
7public function withValidator($validator)
8{
9 // checks user current password
10 // before making changes
11 $validator->after(function ($validator) {
12 if ( !Hash::check($this->current_password, $this->user()->password) ) {
13 $validator->errors()->add('current_password', 'Your current password is incorrect.');
14 }
15 });
16 return;
17 }
在我们的与Valdator
方法中,我们添加了一个之后
链接,该函数将在所有验证检查完成后执行。
在我们的后
链接中,我们将用户提供的密码与其数据库中的密码进行比较。
$this->current_password
给了我们current_password
表单字段值,而Laravel允许我们使用$this->user()
访问当前身份验证的用户,因此$this->user()->password
给了我们用户存储在数据库中的哈希密码。
两种密码使用Hash
面板的检查
方法进行比较。
如果哈希检查失败,则将添加错误到验证器中,键为current_password
,使用$validator->errors()->add('current_password',
您的当前密码不正确。
这里是我们完整的UpdateProfile
表格请求。
1<?php
2
3namespace App\Http\Requests;
4
5use Illuminate\Foundation\Http\FormRequest;
6
7use Illuminate\Support\Facades\Hash;
8
9class UpdateProfile extends FormRequest
10{
11 /**
12 * Determine if the user is authorized to make this request.
13 *
14 * @return bool
15 */
16 public function authorize()
17 {
18 return true;
19 }
20
21 /**
22 * Get the validation rules that apply to the request.
23 *
24 * @return array
25 */
26 public function rules()
27 {
28 return [
29 'name' => 'required|string|max:255',
30 'password' => 'nullable|required_with:password_confirmation|string|confirmed',
31 'current_password' => 'required',
32 ];
33 }
34
35 /**
36 * Configure the validator instance.
37 *
38 * @param \Illuminate\Validation\Validator $validator
39 * @return void
40 */
41 public function withValidator($validator)
42 {
43 // checks user current password
44 // before making changes
45 $validator->after(function ($validator) {
46 if ( !Hash::check($this->current_password, $this->user()->password) ) {
47 $validator->errors()->add('current_password', 'Your current password is incorrect.');
48 }
49 });
50 return;
51 }
52}
步骤三:设置控制器
要使用我们的表单请求,我们需要在我们的控制器操作中键入提示。
执行以下命令来生成配置文件控制器。
1php artisan make:controller ProfileController
打开app/Http/Controllers/ProfileController.php
文件并添加以下控制器操作。
1public function __construct()
2{
3 $this->middleware('auth');
4}
5
6/**
7 * Show the form for editing the specified resource.
8 *
9 * @param \App\User $user
10 * @return \Illuminate\Http\Response
11 */
12public function edit(Request $request, User $user)
13{
14 // user
15 $viewData = [
16 'user' => $user,
17 ];
18 // render view with data
19 return view('profile.edit', $viewData);
20}
21
22/**
23 * Update the specified resource in storage.
24 *
25 * @param \Illuminate\Http\Request $request
26 * @param \App\User $user
27 * @return \Illuminate\Http\Response
28 */
29public function update(UpdateProfile $request, User $user)
30{
31 // form data
32 $data = $request->all();
33 $user->update($data);
34 return redirect(route('profile.edit', ['user' => $user]))
35 ->with('info', 'Your profile has been updated successfully.');
36}
配置文件控制器的构建器设置了Auth
中间程序,以确保用户在编辑其个人资料之前已登录。
编辑
操作为视图提供视图数据,而更新
操作更新用户配置文件并重定向到编辑配置文件页面,并提供相应的闪存消息。
注意编辑
操作的签名,我们已经键入了UpdateProfile
请求,这就是我们需要做的,以启动我们UpdateProfile
表单请求中的验证。
您还需要在控制器类声明之前代号表单请求和用户模型。
1use App\Http\Requests\UpdateProfile;
2use App\User;
步骤 4 – 设置受保护的路径和数据突变器
打开app/routes/web.php
文件,并在控制器操作中添加以下代码。
1Route::get('/profile/{user}/edit', 'ProfileController@edit')->name('profile.edit');
2Route::put('/profile/{user}', 'ProfileController@update')->name('profile.update');
根据我们之前在我们的表单请求中添加的验证规则,可以通过一个无效
密码。
在任何情况下,用户(或应用程序开发人员)都不会希望他们的密码设置为null
或空串。
为了确保用户的密码只有在他们提供密码时才会设置,我们将使用 Eloquent ORM的突变器。
打开app/User.php
文件并添加以下代码。
1// Only accept a valid password and
2// hash a password before saving
3public function setPasswordAttribute($password)
4{
5 if ( $password !== null & $password !== "" )
6 {
7 $this->attributes['password'] = bcrypt($password);
8 }
9}
语气变异器必须遵循命名方案设置<camel-cased-attribute-name>Attribute
。
由于我们声明了密码
属性的一个突变体,因此我们命名了这种突变体为setPasswordAttribute
。
突变函数通过了被设置的值,在我们的突变器中是$password
变量。
在我们的突变器中,我们检查$password
变量是否为null或一个空串,并使用$this->attributes[password]
在我们的模型中设置它。
此外,请注意,密码在保存之前被哈希,所以我们不必在我们的应用程序中其他地方进行。
默认的LaravelAuth/RegisterController
和Auth/ResetPasswordController
在坚持到数据库之前也对密码进行哈希,所以我们需要在声明上述突变器后更新各个控制器中的创建
和重置Password
方法。
打开app/Http/Controllers/Auth/RegisterController.php
文件并添加以下代码。
1/**
2 * Create a new user instance after a valid registration.
3 *
4 * @param array $data
5 * @return \App\User
6 */
7protected function create(array $data)
8{
9 return User::create([
10 'name' => $data['name'],
11 'email' => $data['email'],
12 'password' => $data['password'],
13 ]);
14}
打开app/Http/Controllers/Auth/ResetPasswordController.php
文件并添加以下代码。
1/**
2 * Reset the given user's password.
3 *
4 * @param \Illuminate\Contracts\Auth\CanResetPassword $user
5 * @param string $password
6 * @return void
7 */
8protected function resetPassword($user, $password)
9{
10 $user->password = $password;
11
12 $user->setRememberToken(Str::random(60));
13
14 $user->save();
15
16 event(new PasswordReset($user));
17
18 $this->guard()->login($user);
19}
对于ResetPasswordController
,您还需要在类声明之前使用的相应类别。
1use Illuminate\Support\Str;
2use Illuminate\Auth\Events\PasswordReset;
我们已经完成了,我们的密码验证按预期工作。
结论
在本指南中,我们看到如何实施额外的密码验证步骤,以确认用户有权访问管理区域,我们已经看到如何创建和设置表单请求以在Laravel应用程序中实施表单验证。
有关验证和表单请求的更多信息,您可以查看 官方Laravel文档。