簡介
在底層代碼中,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
,會發現該文件已經被更新:
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,配置如下:
<?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
選項。
<?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一樣,你也可以自定義:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateAdminsTable extends Migration { /** * Run the migrations. * * @return void */ 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(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('admins'); } }
由於后台一般只需要登錄功能,所以來給 admins
表填充一些數據:
php artisan make:seeder AdminsTableSeeder
執行完命令后將會在 database/seeds
目錄下生成 AdminsTableSeeder.php
文件。接下來我們定義一個數據模型工廠,在 database/factories/ModelFactory.php
中添加如下代碼:
<?php /* |-------------------------------------------------------------------------- | Model Factories |-------------------------------------------------------------------------- | | Here you may define all of your model factories. Model factories give | you a convenient way to create models for testing and seeding your | database. Just tell the factory how a default model should look. | */ $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
中填充數據:
<?php use Illuminate\Database\Seeder; class AdminsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { factory('App\Models\Admin',3)->create([ 'password' => bcrypt('123456') ]); } }
填充數據弄好后,在 DatabaseSeeder.php
中加入 AdminsTableSeeder
類
<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // $this->call(UsersTableSeeder::class); $this->call(AdminsTableSeeder::class); } }
最后執行遷移命令:
php artisan migrate --seed
OK,我們在查看數據庫:
修改Admin模型類如下:
<?php namespace App\Models; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class Admin 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', ]; }
后台用戶認證路由及控制器
使用Artisan命令創建控制器:
php artisan make:controller Admin/LoginController php artisan make:controller Admin/DashboardController
編輯 Admin/LoginController.php
,代碼如下:
<?php namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login / registration. * * @var string */ protected $redirectTo = '/admin/dash'; protected $username; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest:admin', ['except' => 'logout']); $this->username = config('admin.global.username'); } /** * 重寫登錄視圖頁面 * @author 晚黎 * @date 2016-09-05T23:06:16+0800 * @return [type] [description] */ public function showLoginForm() { return view('admin.login.index'); } /** * 自定義認證驅動 * @author 晚黎 * @date 2016-09-05T23:53:07+0800 * @return [type] [description] */ protected function guard() { return auth()->guard('admin'); } }
在 LoginController
中我們在構造函數中修改了 guest
中間件,用來跳轉不同路由:
- app\Http\Middleware\RedirectIfAuthenticated.php
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; 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()) { // 根據不同 guard 跳轉到不同的頁面 $url = $guard ? 'admin/dash':'/home'; return redirect($url); } return $next($request); } }
編輯 Admin/DashboardController.php
,代碼如下:
<?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; class DashboardController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth.admin:admin'); } /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ public function index() { dd('后台首頁,當前用戶名:'.auth('admin')->user()->name); } }
在 DashboardController
構造函數中我們添加了一個 auth.admin
Middleware
,這個是我們自定義的,所以我們要來新建一個 Middleware
:
php artisan make:middleware AdminAuthMiddleware
編輯 AdminAuthMiddleware
:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class AdminAuthMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ 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
中注冊:
protected $routeMiddleware = [ ...... 'auth.admin' => \App\Http\Middleware\AdminAuthMiddleware::class, ...... ];
在 routes/web.php
中添加如下路由:
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
目錄下登錄及注冊表單提交地址:
{{ url('/login') }} -> {{ route('admin.login') }}
OK,在瀏覽器中訪問http://blog.me/admin/login
測試:
點擊login,頁面跳轉到http://blog.me/admin/dash
,說明后台登錄成功!
OK,至此我們已經完成前后台用戶同時登錄認證功能。 Enjoy it !
轉帖要厚道,帖子地址
http://laravelacademy.org/post/5925.html