準備工作:
1、下載laravel框架
2、配置好專案(資料庫連線以及虛擬主機)
開始:
前臺使用者認證laravel已經為我們寫好了,此部分可參考官方文件
建立模型(以adminstrator
為例)
php artisan make:model Models/Adminstrator -m
編寫administrator表遷移
Schema::create(`administrators`, function (Blueprint $table) {
$table->engine = `InnoDB`;
$table->increments(`id`);
$table->string(`login_name`)->unique();
$table->string(`display_name`)->nullable();
$table->string(`password`);
$table->string(`avatar`)->nullable();
$table->rememberToken();
$table->tinyInteger(`status`)->default(1);
$table->timestamps();
});
編寫administrator模型
<?php
namespace AppModels;
use IlluminateAuthAuthenticatable;
use IlluminateDatabaseEloquentModel;
use IlluminateContractsAuthAuthenticatable as AuthenticatableContract;
class Administrator extends Model implements AuthenticatableContract
{
use Authenticatable;
protected $fillable = [
`login_name`, `password`
];
protected $hidden = [
`password`, `remember_token`
];
}
建立後臺配置檔案admin.php
,在return陣列中寫入
`auth` => [
`guards` => [
`administrator` => [
`driver` => `session`,
`provider` => `administrators`,
],
],
`providers` => [
`administrators` => [
`driver` => `eloquent`,
`model` => AppModelsAdministrator::class,
],
],
],
建立後臺使用者認證中介軟體Authenticate
,執行:
php artisan make:middleware Admin/Authenticate
修改handle方法:
<?php
/**
* 使用者認證中介軟體
*/
namespace AppHttpMiddlewareAdmin;
use Closure;
use IlluminateSupportFacadesAuth;
class Authenticate
{
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::guard(`administrator`)->guest() && !$this->shouldPassThrough($request)) {
return redirect()->guest(admin_base_path(`login`));
}
return $next($request);
}
/**
* Determine if the request has a URI that should pass through verification.
*
* @param IlluminateHttpRequest $request
*
* @return bool
*/
protected function shouldPassThrough($request)
{
$excepts = [
admin_base_path(`login`),
admin_base_path(`logout`),
];
foreach ($excepts as $except) {
if ($except !== `/`) {
$except = trim($except, `/`);
}
if ($request->is($except)) {
return true;
}
}
return false;
}
}
建立AdminServiceProvider
,執行:
php artisan make:provider AdminServiceProvider
編寫:
<?php
namespace AppProviders;
use IlluminateSupportServiceProvider;
class AdminServiceProvider extends ServiceProvider
{
/**
* 路由中介軟體
* @var array
*/
protected $routeMiddleware = [
`admin.auth` => AppHttpMiddlewareAdminAuthenticate::class,
`admin.pjax` => SpatiePjaxMiddlewareFilterIfPjax::class,
`admin.log` => AppHttpMiddlewareAdminLogOperation::class,
];
/**
* 中介軟體組
* @var array
*/
protected $middlewareGroups = [
`admin` => [
`admin.auth`,
`admin.pjax`,
`admin.log`,
],
];
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
if (file_exists($routes = base_path(`routes/admin.php`))) {
$this->loadRoutesFrom($routes);
}
}
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->loadAdminAuthConfig();
$this->registerRouteMiddleWare();
}
/**
* 註冊路由中介軟體
*/
public function registerRouteMiddleWare()
{
// 註冊路由中介軟體
foreach ($this->routeMiddleware as $key => $middleware) {
app(`router`)->aliasMiddleware($key, $middleware);
}
// 註冊路由中介軟體組
foreach ($this->middlewareGroups as $key => $middleware) {
app(`router`)->middlewareGroup($key, $middleware);
}
}
/**
* Setup auth configuration.
*
* @return void
*/
protected function loadAdminAuthConfig()
{
config(array_dot(config(`admin.auth`, []), `auth.`));
}
}
在config/app.php
中註冊provider和facades
`providers` => [
...,
AppProvidersAdminServiceProvider::class,
]
`aliases` => [
...,
`Admin` => AppFacadesAdminAdmin::class,
]
建立登入表單驗證類,執行:
php artisan make:request AdministratorLoginRequest
重寫其父類rules
及messages
方法:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
class AdministratorLoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
`login_name` => `required`,
`password` => [`required`, `min:6`] //密碼必須,最小長度為6
];
}
public function messages()
{
return [
`login_name.required` => `請輸入使用者名稱`,
`password.required` => `請輸入密碼`,
`password.min` => `密碼至少6位`,
];
}
}
建立登入控制器,執行:
php artisan make:controller Admin/Auth/LoginController
編寫登入方法:
<?php
namespace AppHttpControllersAdminAuth;
use AppHttpRequestsAdministratorLoginRequest;
use IlluminateHttpRequest;
use AppHttpControllersController;
use IlluminateSupportFacadesAuth;
class LoginController extends Controller
{
/**
* 登入表單
* @return IlluminateContractsViewFactory|IlluminateViewView
*/
public function getLoginForm()
{
if (!Auth::guard(`administrator`)->guest()) {
return redirect(config(`admin.route.prefix`));
}
return view(admin_view_base_path(`auth.login.index`));
}
/**
* 登入操作
* @param AdministratorLoginRequest $loginRequest
* @return IlluminateHttpRedirectResponse|IlluminateRoutingRedirector
*/
public function postLogin(AdministratorLoginRequest $loginRequest)
{
$postData = $loginRequest->only(`login_name`, `password`, `remember`);
$result = Auth::guard(`administrator`)->attempt($postData, $loginRequest->filled(`remember`));
if ($result) {
admin_toast(`登入成功`);
$loginRequest->session()->regenerate();
return redirect()->intended(config(`admin.route.prefix`));
}else{
return redirect()->back()->withInput()
->withErrors([
`login_name` => `使用者名稱或密碼錯誤`
]);
}
}
/**
* 登出登入
* @return IlluminateHttpRedirectResponse|IlluminateRoutingRedirector
*/
public function postLogout()
{
Auth::guard(`administrator`)->logout();
session()->forget(`url.intented`);
return redirect(config(`admin.route.prefix`));
}
}
至此,認證業務已經完成,接下來進行完善,使系統能夠跑起來
建立檢視檔案(ps:1、控制器中使用的admin_view_base_path
為自定義函式,指向後臺檢視檔案主目錄。2、檢視採用AdminLTE框架)
login.blade:form
<form action="{{ admin_base_path(`login`) }}" method="post">
@csrf
<div class="form-group has-feedback">
<input type="text" class="form-control {{ $errors->has(`login_name`) ? ` is-invalid` : `` }}"
placeholder="登 錄 名" name="login_name" value="{{ old(`login_name`) }}" required autofocus>
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
@if ($errors->has(`login_name`))
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first(`login_name`) }}</strong>
</span>
@endif
</div>
<div class="form-group has-feedback">
<input type="password" class="form-control {{ $errors->has(`password`) ? ` is-invalid` : `` }}"
placeholder="密 碼" name="password" required>
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
@if ($errors->has(`password`))
<span class="invalid-feedback">
<strong class="text-danger">{{ $errors->first(`password`) }}</strong>
</span>
@endif
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" name="remember" {{ old(`remember`) ? `checked` : `` }}> 記住我
</label>
</div>
</div>
<!-- /.col -->
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">登 錄</button>
</div>
<!-- /.col -->
</div>
</form>
建立後臺home控制器,執行:
php artisan make:controller Admin/Home/HomeController
編寫index方法返回檢視
<?php
namespace AppHttpControllersAdminHome;
use IlluminateHttpRequest;
use AppHttpControllersController;
class HomeController extends Controller
{
//
public function index()
{
return view(admin_view_base_path(`home.index`));
}
}
若僅作登入之後跳轉測試,home檢視中保留登出按鈕即可,例:
home.blade
<div class="pull-right">
<a class="btn btn-default btn-flat" href="/admin/logout"
onclick="event.preventDefault();
document.getElementById(`logout-form`).submit();">
{{ __(`注 銷`) }}
</a>
</div>
<form id="logout-form" class="hide" action="{{ admin_base_path(`logout`) }}" method="POST" style="display: none;">
@csrf
</form>
編輯配置檔案config.admin.php
,加入以下配置:
`route` => [
`prefix` => `admin`,
`namespace` => `App\Http\Controllers\Admin`,
`middleware` => [`web`, `admin`],
],
編寫路由檔案routes/admin.php
<?php
use IlluminateRoutingRouter
Route::group([
`prefix` => config(`admin.route.prefix`),
`namespace` => config(`admin.route.namespace`),
`middleware` => config(`admin.route.middleware`),
], function (Router $router) {
$router->get(`/`, `HomeHomeController@index`);
$router->get(`login`, `AuthLoginController@getLoginForm`);
$router->post(`login`, `AuthLoginController@postLogin`);
$router->post(`logout`, `AuthLoginController@postLogout`);
});
資料表遷移與填充: 修改database/seeds/DatabaseSeeder
<?php
use IlluminateDatabaseSeeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application`s database.
*
* @return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
DB::table(`administrators`)->insert(
[
`login_name` => `admin`,
`display_name` => `超級管理員`,
`password` => bcrypt(`123456`),
`created_at` => date(`Y-m-d H:i:s`, time()),
`updated_at` => date(`Y-m-d H:i:s`, time()),
]
);
}
}
執行:
php artisan migrate //資料表遷移
php artisan db:seed //資料填充
如果前臺使用了laravel框架使用者認證的話,需要重寫框架生成的LoginController
的logout
方法。防止前臺使用者登出的時候清除後臺使用者的session。(ps:框架自帶使用者認證在登出時會清空所有session)
/**
* 重寫前臺登出操作
* @param Request $request
* @return IlluminateHttpRedirectResponse|IlluminateRoutingRedirector
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->forget(`uri.intented`);
return redirect(`/`);
}
至此,後臺使用者登入全部完成。enjoy it!