1、後臺Admin模塊php
後臺管理是有管理員的,甚至超級管理員,因此在設計數據表的時候,就會有2個方案,一個方案是共用users數據表,添加is_admin,is_superAdmin字段來進行驗證,或者將用戶編到不一樣的組裏面,另外一個方案是,單首創建admins數據表來進行管理(這樣前臺和後臺是兩個事件,前臺用戶是沒有機會操做後臺相關功能的,也就是徹底隔離了)laravel
我採用第二種(實習快四個月了,跟了2個完整項目是這樣~)git
我在上一篇說到,我使用的是laravel-module,因此相關初始配置再也不贅述。github
使用artisan hd:module Admin後,可訪問後臺界面partTime.com/adminweb
2、動態分層管理後臺菜單設計模式
3、建立Guard守衛實現先後臺帳號分離api
1. 守衛Guard配置session
請仔細看下面代碼中的註釋~app
1 <?php 2 3 return [ 4 5 /* 6 |-------------------------------------------------------------------------- 7 | Authentication Defaults 8 |-------------------------------------------------------------------------- 9 | 10 | This option controls the default authentication "guard" and password 11 | reset options for your application. You may change these defaults 12 | as required, but they're a perfect start for most applications. 13 | defaults:默認使用web守衛者 14 | guard:守衛者,守衛web(也就是前臺的全部操做) 15 | passwords:守衛者對應的數據表,也便是根據哪一張來進行守衛 16 | 17 */ 18 19 'defaults' => [ 20 'guard' => 'web', 21 'passwords' => 'users', 22 ], 23 24 /* 25 |-------------------------------------------------------------------------- 26 | Authentication Guards 27 |-------------------------------------------------------------------------- 28 | 29 | Next, you may define every authentication guard for your application. 30 | Of course, a great default configuration has been defined for you 31 | here which uses session storage and the Eloquent user provider. 32 | 33 | All authentication drivers have a user provider. This defines how the 34 | users are actually retrieved out of your database or other storage 35 | mechanisms used by this application to persist your user's data. 36 | 37 | Supported: "session", "token" 38 | 這部分是定義守衛者 39 | driver:經過什麼方式來檢索用戶,要麼session會話,要麼token令牌 40 | provider:對應的數據表 41 | 42 */ 43 44 'guards' => [ 45 'web' => [ 46 'driver' => 'session', 47 'provider' => 'users', 48 ], 49 'admin' => [ 50 'driver' => 'session', 51 'provider' => 'admins', 52 ], 53 54 'api' => [ 55 'driver' => 'token', 56 'provider' => 'users', 57 ], 58 ], 59 60 /* 61 |-------------------------------------------------------------------------- 62 | User Providers 63 |-------------------------------------------------------------------------- 64 | 65 | All authentication drivers have a user provider. This defines how the 66 | users are actually retrieved out of your database or other storage 67 | mechanisms used by this application to persist your user's data. 68 | 69 | If you have multiple user tables or models you may configure multiple 70 | sources which represent each model / table. These sources may then 71 | be assigned to any extra authentication guards you have defined. 72 | 73 | Supported: "database", "eloquent" 74 | 由於Laravel對數據表的操做都是經過模型Model,因此須要再此定義 75 | Admin模型定義:php artisan make:model Admin -fm(f表明模型工廠,m表明數據遷移表) 這種方式很方便,比用一個一個去建立了~~不使用此方法的話,萬一表定義錯了,你還得告訴模型你使用的是拿一張表 76 | 77 */ 78 79 'providers' => [ 80 'users' => [ 81 'driver' => 'eloquent', 82 'model' => App\User::class, 83 ], 84 'admins' => [ 85 'driver' => 'eloquent', 86 'model' => App\Admin::class, 87 ], 88 89 // 'users' => [make 90 // 'driver' => 'database', 91 // 'table' => 'users', 92 // ], 93 ], 94 95 /* 96 |-------------------------------------------------------------------------- 97 | Resetting Passwords 98 |-------------------------------------------------------------------------- 99 | 100 | You may specify multiple password reset configurations if you have more 101 | than one user table or model in the application and you want to have 102 | separate password reset settings based on the specific user types. 103 | 104 | The expire time is the number of minutes that the reset token should be 105 | considered valid. This security feature keeps tokens short-lived so 106 | they have less time to be guessed. You may change this as needed. 107 | 108 */ 109 110 'passwords' => [ 111 'users' => [ 112 'provider' => 'users', 113 'table' => 'password_resets', 114 'expire' => 60, 115 ], 116 ], 117 118 ];
注意:less
此時建立出來的Admin.php以下,實際上是不完整的喲,往下看~
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Admin extends Model { // }
2. View、Controller的配置
View可使用和前臺同樣的界面,也能夠本身修改界面,無非就是個樣式問題
Controller和前臺同樣
因此若是同樣的話,直接複製粘貼,修改控制器的namespace就好啦~
若是你使用了不一樣UI,卻發現界面不對的話,在LoginController添加如下方法
// 這是指定顯示哪個界面 public function showLoginForm() { return view('admin::auth.login'); }
3. 路由配置
方法一:
1 // middleware中間件 2 // prefix:前綴(可使用artisan route:list查看)好比:前臺登錄:http://parttime.com/login,後臺登錄:http://parttime.com/admin/login(其中的admin就是屬性prefix指定的) 3 Route::group( 4 ['middleware' => 'web', 'prefix' => 'admin', 'namespace' => 'Modules\Admin\Http\Controllers'], 5 function () { 6 Auth::routes(); 7 } 8 );
若是用這種方式的話,那麼form表單的action屬性就得寫成action="/admin/login"
方法二:
1 Route::group( 2 ['middleware' => 'web', 'prefix' => 'admin', 'namespace' => 'Modules\Admin\Http\Controllers'], 3 function () { 4 Route::name('admin.')->group( 5 function () { 6 Auth::routes(); 7 } 8 ); 9 } 10 );
若是用這種方式的話,那麼form表單的action屬性就得寫成action="{{route('admin.login')}}"
4. 錯誤
錯誤一:郵箱不能爲空
LoginController中use了一個AuthenticatesUsers,它裏面有那個方法username()是指定驗證的用戶名是誰,默認是email,咱們能夠對它進行重寫
public function username() { return 'name';// 或者你想驗證的屬性 }
錯誤二:用戶名密碼錯誤
爲了方便測試,咱們將admins表中的第一條數據進行了修改,所以排除Factory、AdminSeeder的錯誤
其實AuthenticatesUsers還有一個guard()方法,它指定使用哪個守衛者,不傳參默認使用web,因此須要對它進行重寫(也就是告訴網頁,此時的url是誰保護的)
protected function guard() { return \Auth::guard('admin'); }
錯誤三:好多英文~
截至目前,Admin.php中只是繼承了Model,它只是實現了對錶的一些操做,好比增刪改查等等,並無守衛者
那咱們來看一下系統默認的User.php模型是怎麼樣的
1 <?php 2 3 namespace App; 4 5 use Illuminate\Notifications\Notifiable; 6 use Illuminate\Foundation\Auth\User as Authenticatable; 7 8 class User extends Authenticatable 9 { 10 use Notifiable; 11 12 /** 13 * The attributes that are mass assignable. 14 * 15 * @var array 16 */ 17 protected $fillable = [ 18 'name', 'email', 'password', 19 ]; 20 21 /** 22 * The attributes that should be hidden for arrays. 23 * 24 * @var array 25 */ 26 protected $hidden = [ 27 'password', 'remember_token', 28 ]; 29 }
咱們能夠模仿它來改造咱們的Admin.php模型
1 <?php 2 3 namespace App; 4 5 use Illuminate\Notifications\Notifiable; 6 use Illuminate\Foundation\Auth\User as Authenticatable; 7 8 class Admin extends Authenticatable 9 { 10 use Notifiable; 11 12 // 13 }
搞定,後臺也能夠登錄啦~ 而後你又會發現一個問題,爲啥跳轉到了前臺登錄界面
錯誤四:跳轉錯誤
其實這裏暗藏了兩個問題:1.爲何跳轉錯誤(確定是和後臺相關的一些配置出了問題)2.爲何跳轉到的是前臺的登錄界面
我們先解決第2個問題:
這是前臺路由配置,Laravel有中間件機制,當前臺用戶沒有登錄的時候,他訪問了網址,就會自動跳轉到登錄界面,而控制這個Controller是前臺的HomeController.php
1 <?php 2 3 /* 4 |-------------------------------------------------------------------------- 5 | Web Routes 6 |-------------------------------------------------------------------------- 7 | 8 | Here is where you can register web routes for your application. These 9 | routes are loaded by the RouteServiceProvider within a group which 10 | contains the "web" middleware group. Now create something great! 11 | 12 */ 13 14 // 主頁面 15 Route::get( 16 '/', 17 function () { 18 return view('welcome'); 19 } 20 ); 21 22 // 前臺登錄、註冊、找回密碼 23 Auth::routes(); 24 25 Route::get('/home', 'HomeController@index')->name('home');
1 <?php 2 3 namespace App\Http\Controllers; 4 5 class HomeController extends Controller 6 { 7 /** 8 * Create a new controller instance. 9 * 10 * @return void 11 */ 12 public function __construct() 13 { 14 $this->middleware('auth'); 15 } 16 17 /** 18 * Show the application dashboard. 19 * 20 * @return \Illuminate\Http\Response 21 */ 22 public function index() 23 { 24 return view('home'); 25 } 26 }
再解決第一個問題:
很簡單,再Admin模塊的LoginController.php中,有一個$redirectTo屬性就是控制跳轉的~
補充:
不管前臺仍是後臺,用戶登錄成功了之後,再經過地址欄訪問登錄界面是不該該出現它的,因此中間件的魅力就能夠凸顯~
4、中間件設置先後臺跳轉不一樣路由
中間件有Laravel已經配置好的(app/Http/Kernel.php),也能夠本身自定義
先後臺的LoginController.php的構造方法以下
1 public function __construct() 2 { 3 $this->middleware('guest')->except('logout');// except:指定的方法或方法組不進行驗證 4 }
guest中間件是對遊客的限制,那麼就會有一個問題:如何指定這個有可能即將登錄的遊客是什麼角色呢,是前臺用戶,仍是後臺管理員?因此guard守衛者再次派上用場
middleware('guest:admin')當不指定admin的時候默認採用web(前臺)守衛者,不然採用指定的守衛者(這裏是admin守衛者)
那麼又產生一個問題:我驗證成功了,如何針對不一樣角色的用戶實現不一樣的跳轉呢?
下面是guest中間件所對應的類實現的方法(暫時忽略$next,這個和設計模式有關,如今還用不到)
邏輯很簡單,判斷是否有傳進來的守衛者,沒有就用默認的web,而後進行跳轉/home(問題就在這裏:無論前臺仍是後臺都是跳轉/home,顯然是不對的,所以須要對其進行修改)
1 <?php 2 3 namespace App\Http\Middleware; 4 5 use Closure; 6 use Illuminate\Support\Facades\Auth; 7 8 class RedirectIfAuthenticated 9 { 10 /** 11 * Handle an incoming request. 12 * 13 * @param \Illuminate\Http\Request $request 14 * @param \Closure $next 15 * @param string|null $guard 16 * @return mixed 17 */ 18 public function handle($request, Closure $next, $guard = null) 19 { 20 if (Auth::guard($guard)->check()) { 21 return redirect('/home'); 22 } 23 24 return $next($request); 25 } 26 }
修改後:
1 <?php 2 3 namespace App\Http\Middleware; 4 5 use Closure; 6 use Illuminate\Support\Facades\Auth; 7 8 class RedirectIfAuthenticated 9 { 10 /** 11 * Handle an incoming request. 12 * 13 * @param \Illuminate\Http\Request $request 14 * @param \Closure $next 15 * @param string|null $guard 16 * 17 * @return mixed 18 */ 19 public function handle($request, Closure $next, $guard = null) 20 { 21 if (Auth::guard($guard)->check()) { 22 // 能夠自行決定跳轉到哪裏~ 23 return redirect($guard == 'admin' ? '/admin' : '/home'); 24 } 25 26 return $next($request); 27 } 28 }
AuthenticatesUsers