简介 在底层代码中,Laravel 的认证组件由 guards 和 providers组成,Guard 定义了用户在每个请求中如何实现认证,例如,Laravel 通过 session guard来维护 Session 存储的状态、Cookie 以及 token guard,token guard 是认证用户发送请求时带的API token。
Provider 定义了如何从持久化存储中获取用户信息,Laravel 底层支持通过 Eloquent 和数据库查询构建器两种方式来获取用户,如果需要的话,你还可以定义额外的 Provider。
相对于Laravel5.2而言,Laravel5.3在底层代码中做了很多修改,方法更加简洁,这个下面会提到。虽然代码改了很多,但是原理都是一样的,我们只需要重写不同的方法而已。
默认认证 首先我们使用Laravel 5.3提供的开箱即用的认证:
php artisan make:auth
该Artisan命令会生成用户认证所需的路由、视图以及HomeController: 认证的路由也一并生成好了,查看路由文件routes/web.php,会发现该文件已经被更新:
1 2 3 Auth::routes (); Route::get ('/home' , 'HomeController@index' );
其中Auth::routes()
定义了登录注册及找回密码路由,/home
为用户认证成功后跳转的路由。
验证 接下来我们先实现前台用户登录,也就是Laravel自带的Users用户表登录。通过生成的默认登录认证,已经写好了所有代码,剩下要做的就是使用迁移命令创建用户认证相关表:
php artisan migrate
执行命令后会生成 users 表和 password_resets 表,分别为用户表和密码重置表。然后我们就可以在浏览器中输入http://blog.me/register 来注册新用户: 我们创建一个 iwanli 的用户,注册成功后直接跳转/home
,并且刚注册的用户名也已经显示出来了: 登录、找回密码功能都已经写好,我就不一一测试了~
自定义用户表登录 首先要看看默认的用户认证配置文件auth.php,配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?php return [ 'defaults' => [ 'guard' => 'web' , 'passwords' => 'users' , ], 'guards' => [ 'web' => [ 'driver' => 'session' , 'provider' => 'users' , ], 'api' => [ 'driver' => 'token' , 'provider' => 'users' , ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent' , 'model' => App\User::class, ], ], 'passwords' => [ 'users' => [ 'provider' => 'users' , 'email' => 'auth.emails.password' , 'table' => 'password_resets' , 'expire' => 60 , ], ], ];
认证是由 guard 和 provider 两部分构成的(参考用户认证文档),defaults 配置是选择哪一个 guard 认证驱动,所以我们在这两个配置项中分别添加一个 admin 和 admins 选项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?php return [ 'defaults' => [ 'guard' => 'web' , 'passwords' => 'users' , ], 'guards' => [ 'web' => [ 'driver' => 'session' , 'provider' => 'users' , ], 'admin' => [ 'driver' => 'session' , 'provider' => 'admins' , ], 'api' => [ 'driver' => 'token' , 'provider' => 'users' , ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent' , 'model' => App\User::class, ], 'admins' => [ 'driver' => 'eloquent' , 'model' => App\Models\Admin::class, ], ], 'passwords' => [ 'users' => [ 'provider' => 'users' , 'email' => 'auth.emails.password' , 'table' => 'password_resets' , 'expire' => 60 , ], ], ];
创建后台用户用户表及Model 接下来我们来实现后台用户登录,使用如下Artisan命令生成后台用户Model:
php artisan make:model Models/Admin -m
带上-m
选项会生成对应迁移文件 *_create_admins_table
,我们定义该数据表字段和users一样,你也可以自定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <?php use Illuminate \Support \Facades \Schema ;use Illuminate \Database \Schema \Blueprint ;use Illuminate \Database \Migrations \Migration ;class CreateAdminsTable extends Migration { public function up ( ) { Schema ::create ('admins' , function (Blueprint $table ) { $table ->increments ('id' ); $table ->string ('name' ); $table ->string ('email' )->unique (); $table ->string ('password' ); $table ->rememberToken (); $table ->timestamps (); }); } public function down ( ) { Schema ::dropIfExists ('admins' ); } }
由于后台一般只需要登录功能,所以来给 admins 表填充一些数据:
php artisan make:seeder AdminsTableSeeder
执行完命令后将会在 database/seeds 目录下生成 AdminsTableSeeder.php 文件。接下来我们定义一个数据模型工厂,在 database/factories/ModelFactory.php 中添加如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php $factory ->define (App\User ::class , function (Faker\Generator $faker ) { static $password ; return [ 'name' => $faker ->name, 'email' => $faker ->safeEmail, 'password' => $password ?: $password = bcrypt ('secret' ), 'remember_token' => str_random (10 ), ]; }); $factory ->define (App\Models\Admin ::class , function (Faker\Generator $faker ) { static $password ; return [ 'name' => $faker ->name, 'email' => $faker ->safeEmail, 'password' => $password ?: $password = bcrypt ('secret' ), 'remember_token' => str_random (10 ), ]; });
模型工厂定义完成后,在 AdminsTableSeeder.php 中填充数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php use Illuminate \Database \Seeder ;class AdminsTableSeeder extends Seeder { public function run ( ) { factory ('App\Models\Admin' ,3 )->create ([ 'password' => bcrypt ('123456' ) ]); } }
填充数据弄好后,在 DatabaseSeeder.php 中加入 AdminsTableSeeder 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php use Illuminate \Database \Seeder ;class DatabaseSeeder extends Seeder { public function run ( ) { $this ->call (AdminsTableSeeder ::class ); } }
最后执行迁移命令:
php artisan migrate --seed
OK,我们在查看数据库:
修改Admin模型类如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?php namespace App \Models ;use Illuminate \Notifications \Notifiable ;use Illuminate \Foundation \Auth \User as Authenticatable ;class Admin extends Authenticatable { use Notifiable ; protected $fillable = [ 'name' , 'email' , 'password' , ]; protected $hidden = [ 'password' , 'remember_token' , ]; }
后台用户认证路由及控制器 使用Artisan命令创建控制器:
1 2 php artisan make :controller Admin/LoginController php artisan make :controller Admin/DashboardController
编辑 Admin/LoginController.php ,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 <?php namespace App \Http \Controllers \Admin ;use App \Http \Controllers \Controller ;use Illuminate \Http \Request ;use Illuminate \Foundation \Auth \AuthenticatesUsers ;class LoginController extends Controller { use AuthenticatesUsers ; protected $redirectTo = '/admin/dash' ; protected $username ; public function __construct ( ) { $this ->middleware ('guest:admin' , ['except' => 'logout' ]); $this ->username = config ('admin.global.username' ); } public function showLoginForm ( ) { return view ('admin.login.index' ); } protected function guard ( ) { return auth ()->guard ('admin' ); } }
在 LoginController 中我们在构造函数中修改了 guest 中间件,用来跳转不同路由:
app\Http\Middleware\RedirectIfAuthenticated.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php namespace App \Http \Middleware ;use Closure ;use Illuminate \Support \Facades \Auth ;class RedirectIfAuthenticated { public function handle ($request , Closure $next , $guard = null ) { if (Auth ::guard ($guard )->check ()) { $url = $guard ? 'admin/dash' :'/home' ; return redirect ($url ); } return $next ($request ); } }
编辑 Admin/DashboardController.php ,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?php namespace App \Http \Controllers \Admin ;use Illuminate \Http \Request ;use App \Http \Requests ;use App \Http \Controllers \Controller ;class DashboardController extends Controller { public function __construct ( ) { $this ->middleware ('auth.admin:admin' ); } public function index ( ) { dd ('后台首页,当前用户名:' .auth ('admin' )->user ()->name); } }
在 DashboardController 构造函数中我们添加了一个 auth.admin Middleware,这个是我们自定义的,所以我们要来新建一个 Middleware:
php artisan make:middleware AdminAuthMiddleware
编辑 AdminAuthMiddleware :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php namespace App \Http \Middleware ;use Closure ;use Illuminate \Support \Facades \Auth ;class AdminAuthMiddleware { public function handle ($request , Closure $next ,$guard = null ) { if (Auth ::guard ($guard )->guest ()) { if ($request ->ajax () || $request ->wantsJson ()) { return response ('Unauthorized.' , 401 ); } else { return redirect ()->guest ('admin/login' ); } } return $next ($request ); } }
在 app\Http\Kernel.php 中注册:
1 2 3 4 5 protected $routeMiddleware = [ ... ... 'auth.admin' => \App\Http\Middleware\AdminAuthMiddleware::class , ... ... ] ;
在 routes/web.php 中添加如下路由:
1 2 3 4 5 6 7 8 Route ::group(['prefix' => 'admin' ,'namespace' => 'Admin' ],function ($router){ $router->get('login' , 'LoginController @showLoginForm')->name('admin .login'); $router->post('login' , 'LoginController @login'); $router->post('logout' , 'LoginController @logout'); $router->get('dash' , 'DashboardController @index'); });
视图文件创建及修改 最后我们要创建后台用户认证对应视图文件,这里我们简单复制默认用户视图模板并稍作修改即可,复制 resources\views\auth\login.blade.php 文件到并重命名 resources\views\admin\login\index.blade.php 。
修改resources\views\admin\login\index.blade.php目录下登录及注册表单提交地址:
1 {{ url ('/login' ) }} -> {{ route ('admin.login' ) }}
OK,在浏览器中访问http://blog.me/admin/login 测试: 点击login,页面跳转到http://blog.me/admin/dash ,说明后台登录成功! OK,至此我们已经完成前后台用户同时登录认证功能。 Enjoy it !