先安裝 Laravel 及 內建的 Authentication
composer create-project --prefer-dist laravel/laravel blog "6.*"
composer require laravel/ui "^1.0" --dev
php artisan ui vue --auth
建立另一個使用者 Model 及 mirgation 檔案,例如: admins。
php artisan make:model Admin
php artisan make:migration create_admins_table
編輯 app/Models/Admin.php 程式碼如下:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
protected $guard = 'admin';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'firstname', 'midname', 'lastname', 'email', 'address', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
編輯 database/migration/[時間序號]_create_admins_table.php 程式碼如下:
<?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('firstname');
$table->string('midname');
$table->string('lastname');
$table->string('email')->unique();
$table->string('address')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('admins');
}
}
建立完成後別忘記把資料表建立起來。這時候會將admins和users資料表同時建立起來。
php artisan migrate
在 config/auth.php 的 guards 段落中新增
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
//提供給後台管理登入用
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
],
在 config/auth.php 的 providers 段落中新增
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
//使用admins資料表
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
在 resources/views/ 目錄下建立一個 admin 目錄,用來放置 admin 的視圖,以免與原有的混在一起。
在 resources/views/ 目錄下新建立 login.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin=anonymous>
<title>Admin</title>
</head>
<body>
<div>
<div>
<div></div>
<div>
<div>
<div>
<form id="sign_in_adm" method="POST" action="{{ route('admin.login.submit') }}">
{{ csrf_field() }}
<h1>Admin Login</h1>
<div>
<input type=email name=email placeholder="Email Address" value="{{ old('email') }}"
required autofocus>
</div>
@if ($errors->has('email'))
<span><strong>{{ $errors->first('email') }}</strong></span>
@endif
<br>
<div>
<input type=password name=password placeholder="Password" required>
</div>
<br>
<div>
<button type=submit>SIGN IN</button>
</div>
</form>
</div>
</div>
</div>
<div></div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin=anonymous>
<title>Admin</title>
</head>
<body>
<div >
<div >
<div ></div>
<div >
<div >
<div >
<form id="sign_in_adm" method="POST" action="{{ route('admin.login.submit') }}">
{{ csrf_field() }}
<h1>Admin Login</h1>
<div >
<input type=email name=email placeholder="Email Address" value="{{ old('email') }}" required autofocus>
</div>
@if ($errors->has('email'))
<span ><strong>{{ $errors->first('email') }}</strong></span>
@endif
<br>
<div >
<input type=password name=password placeholder="Password" required>
</div>
<br>
<div >
<button type=submit >SIGN IN</button>
</div>
</form>
</div>
</div>
</div>
<div ></div>
</div>
</div>
</body>
</html>
在 resources/views/ 目錄下新建立 dashboard.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin=anonymous>
<title>Admin Dashboard</title>
</head>
<body>
<div>
<div>
<div></div>
<div>
<div>
<div>
<h1>Welcome To Admin Dashboard</h1>
</div>
</div>
<br><br>
登入帳號: {{ $adminuser->email }}
<br><br>
<a href="/admin/logout">Logout</a>
</div>
<div></div>
</div>
</div>
</body>
</html>
在 app/Http/Controllers/Auth 目錄中新增一個 controller 給 admin 用,這個負責用來控制登入與登出。
php artisan make:controller Auth\AdminLoginController
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
use Route;
class AdminLoginController extends Controller
{
//先經過 middleware
public function __construct()
{
$this->middleware('guest:admin', ['except' => ['logout']]);
}
//顯示 admin.login 視圖
public function showLoginForm()
{
return view('admin.login');
}
//登入
public function login(Request $request)
{
// 驗證表單資料
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
// 將表單資料送去驗證
if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) {
//驗證無誤轉入 admin.dashboard
return redirect()->intended(route('admin.dashboard'));
}
// 驗證失敗 返回並拋出表單內容 只拋出 email 與 remember 欄位資料
return redirect()->back()->withInput($request->only('email', 'remember'));
}
//登出
public function logout()
{
Auth::guard('admin')->logout();
return redirect('/admin');
}
}
另外新增一個 controller 給 admin 用,這個負則用來控制 Admin 登入後的相關 function。(例如: 顯示 dashboard 或其他功能)
php artisan make:controller AdminController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use View;
class AdminController extends Controller
{
/**
* Create a new controller instance.
* 進到這個控制器需要透過middleware檢驗是否為後台的使用者
* @return void
*/
public function __construct()
{
$this->middleware('auth:admin');
}
/**
* 顯示 dashboard.
* 並將 使用者的資料拋出
* @return \Illuminate\Http\Response
*/
public function dashboard()
{
$adminuser = Auth::user();
return View::make('admin.dashboard', compact('adminuser'));
}
}
編輯 routes/web.php 路由檔案,新增 admin 用的路由。
//admin用的路由 網址看起來就像 https://localhost/{admin}/{名稱}
Route::prefix('admin')->group(function() {
Route::get('/login','Auth\AdminLoginController@showLoginForm')->name('admin.login');
Route::post('/login', 'Auth\AdminLoginController@login')->name('admin.login.submit');
Route::get('/logout', 'Auth\AdminLoginController@logout')->name('admin.logout');
Route::get('/', 'Auth\AdminLoginController@showLoginForm')->name('admin');
Route::get('/dashboard', 'AdminController@dashboard')->name('admin.dashboard');
}) ;
編輯 app/Exceptions/Handler.php 檔案,新增一個切換判斷是從哪個地方來的使用者並給出正確的位置視圖。
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
//新增以下使用兩個class
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Arr;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*
* @throws \Exception
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Exception
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = Arr::get($exception->guards(), 0);
//用來判斷是前台還是後台來的使用者並轉到正確的登入頁面
switch ($guard) {
case 'admin':
$login='admin.login';
break;
default:
$login='login';
break;
}
return redirect()->guest(route($login));
}
}
編輯 app/Http/Middleware/RedirectifAuthenticated.php 檔案,當使用者被確認後,透過 middleware 來將使用者導到正確的視圖或功能位置。
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
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)
{
// 舊有的判斷導到 Auth 的 RouteServiceProvider::HOME
// if (Auth::guard($guard)->check()) {
// return redirect(RouteServiceProvider::HOME);
// }
// return $next($request);
//當使用者被確認後,判斷是前台還是後台來的使用者並轉到正確的頁面位置
switch ($guard) {
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect()->route('admin.dashboard');
}
default:
if (Auth::guard($guard)->check()) {
return redirect('/');
}
break;
}
return $next($request);
}
}
完成。登入測試!