通过内置脚手架快速实现用户认证
今天开始我们将开启用户认证与授权系列,主要规划了以下内容:
- 通过内置命令快速实现登录认证功能
- 用户登录注册流程及多字段登录实现
- 基于多表的用户认证功能实现
- 基于 API 的用户认证功能实现
- 用户认证相关事件触发及监听
- 邮箱验证及找回密码功能实现
- 不同系统用户单点登录实现
- 基于 ACL 的用户权限管理实现
- 基于 RBAC 的用户权限管理实现
希望通过这个系列的学习,可以帮助你彻底掌握 Laravel 框架中用户认证与授权相关功能的实现。首先我们从用户认证开始。
系统自带脚手架
Laravel 框架开箱为我们提供了一些用户认证需要的脚手架代码。包括数据库迁移文件、用户模型、用户认证中间件和控制控制器等。我们先来简单介绍下它们。
数据库迁移
新安装的 Laravel 应用都包含下面两个迁移文件,分别用于创建用户表和密码重置表,这两张表在用户认证与找回密码过程中会用到:
User 模型类
此外,Laravel 框架还在 app
目录下为我们提供了与用户表相对应的模型类 User
,在基于 Eloquent 模型驱动的认证提供者中,我们通过该模型类实现登录认证,你可以在配置文件 config/auth.php
中查看相应的配置:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
如果你不是通过 User
模型类进行认证,可以在这里修改对应的 model
配置项。如果你不想通过 Eloquent 模型驱动,而是基于原生的数据库查询,可以注释掉 eloquent
对应的 users
配置,启用下面这个 database
对应的 users
配置,这样的话就是直接去查询 users
表,而不是通过模型类进行认证了。
回到我们的默认配置,我们看下 User
模型类代码:
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
如果某个模型类需要用于认证,必须继承自 Illuminate\Foundation\Auth\User
基类,否则会报错。然后我们在这个模型类中使用了 Notifiable
Trait,里面提供了用户发送通知的相关方法。我们在白名单 $fillable
中配置了三个字段,这三个字段会在登录和注册时用到。最后,我们还配置了 $hidden
属性,在返回查询结果的时候将敏感信息过滤掉,避免安全隐患。
认证中间件
Laravel 框架内置了几个认证中间件,用于在需要认证的路由中拒绝未认证用户发起的请求,或者将已登录用户重定向到认证页面,打开 app/Http/Kernel.php
,可以在 $routeMiddleware
看到对应的路由中间件:
我们平时主要用到的是 auth
中间件和 guest
中间件,auth.basic
用于基于 HTTP 的简单认证,很少用到,throttle
中间件会在用户多次登录失败时使用,单位登录失败超过指定次数不允许继续发起登录请求,提高系统安全性。
auth
中间件是 \App\Http\Middleware\Authenticate::class
的别名,Authenticate
主要用于将未登录用户重定向到登录页面:
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
return route('login');
}
}
guest
中间件是 \App\Http\Middleware\RedirectIfAuthenticated::class
的别名,RedirectIfAuthenticated
主要用于将已登录用户重定向到认证后页面,未登录则继续原来的请求:
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}
认证控制器
最后,Laravel 还为我们开箱提供了注册、登录、重置密码、邮箱验证、忘记密码对应的控制器:
其中 ForgotPasswordController
用于忘记密码后通过填写注册邮箱发送重置密码链接,对应逻辑位于 Illuminate\Foundation\Auth\SendsPasswordResetEmails
Trait 中。
LoginController
用于用户登录和退出,对应逻辑位于 Illuminate\Foundation\Auth\AuthenticatesUsers
Trait 中。
RegisterController
用于新用户注册,对应逻辑位于 Illuminate\Foundation\Auth\RegistersUsers
Trait 中。
ResetPasswordController
用于重置密码,对应逻辑位于 Illuminate\Foundation\Auth\ResetsPasswords
Trait 中。
上述控制器的构造函数中都应用了 guest
中间件(退出功能除外),表示这些控制器提供的方法都是给未登录用户使用的。
VerificationController
是 Laravel 5.7 新提供的,用于新注册用户邮箱验证,对应逻辑位于 Illuminate\Foundation\Auth\VerifiesEmails
Trait 中。关于邮箱验证功能后面单独讲。
如果你的系统不需要用户认证功能的话,大可以把这些控制器和中间件都删掉,否则这些就是「僵尸」代码,占个位置而已,没什么用。不过如果你需要用到用户认证,尤其是通过系统自带的 make:auth
命令快速实现用户认证,这些「僵尸」代码就会像启动了发动机的机器一样,迅速与路由、视图无缝整合到一起,提供完整的用户认证解决方案。
接下来,就让这些控制器、中间件运转起来。
通过 Artisan 命令快速实现注册登录
我们可以自己编写用户认证路由、视图然后对接到这些控制器,提供用户认证功能,不过,Laravel 开箱为我们提供了 Artisan 命令 make:auth
,运行该命令可以帮助我们在最短时间内完成认证路由注册和认证视图(兼容 Bootstrap 4)发布,既然如此,为什么不用这个自带的命令呢?而且通过该命令提供的路由和视图可以和上面介绍的脚手架代码无缝对接,不需要编写任何额外的代码就可以让新安装的 Laravel 应用具备用户认证相关功能,这,也许就是原装的好处吧。
好了,废话不多说,下面我们在系统根目录下运行如下命令激活「休眠」的用户认证功能:
php artisan make:auth # 注册认证路由、发布认证视图
php artisan migrate # 创建认证相关数据表,如果之前已经运行过,可以跳过
npm run dev # 编译前端资源,如果之前已经运行过,可以跳过
make:auth
命令会在 routes/web.php
中注册以下路由:
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
home
路由是用户认证成功后默认跳转路由,Auth::routes()
则包含以下路由定义:
// Authentication Routes...
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');
// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
// Email Verification Routes...
$this->get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
$this->get('email/verify/{id}', 'Auth\VerificationController@verify')->name('verification.verify');
$this->get('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
此外,该命令还会在 resources/views
下发布以下登录认证相关的视图文件:
resources/views/home.blade.php
resources/views/layouts/app.blade.php
resources/views/auth/login.blade.php
resources/views/auth/register.blade.php
resources/views/auth/verify.blade.php
resources/views/auth/passwords/email.blade.php
resources/views/auth/passwords/reset.blade.php
这样,不需要编写任何代码,只需要简单运行几个命令,就可以在 Laravel 应用中实现登录认证功能了。这样,我们点击首页的右上角的登录按钮,就可以进入登录页面了:
当然,如果我们还没有注册用户的话,暂时还不能登录,下一篇教程,我们将演示用户注册与登录功能,并实现同时支持多个字段的登录。
7 Comments
怎么修改登录验证提示?
为什么我下的版本没有Auth 下面LoginController? "php": "^7.1.3", "fideloper/proxy": "^4.0", "laravel/framework": "5.8.*", "laravel/tinker": "^1.0"
你删除过吧 默认是有的 https://github.com/laravel/laravel/tree/master/app/Http/Controllers/Auth
神马情况?laravel6没有了php artisan make:auth命令了么?执行直接异常 Command "make:auth" is not defined.
laravel6移除了php artisan make:auth命令,需要的时候执行composer require laravel/ui 下载扩展,再执行php artisan ui vue --auth,这里的vue可以换成 react或者bootstrap,决定使用的前端js框架。
学院君您好,这里想问下 laravel6去除了php artisan make:auth 将使用php artisan ui vue --auth。然后相应的功能跟之前也一样,页面也有 但是样式没有了,看了下是没有加载vue的npm。请问这里需要加载 npm install && npm run dev这个命令吗?是直接在blog项目中还是在laradock里面呢?谢谢
当然需要 参考登录认证文档:https://xueyuanjun.com/post/19948.html,不涉及数据库的操作哪里执行都是一样的