准备工作:
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 App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable 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' => \App\Models\Administrator::class,
],
],
],
创建后台用户认证中间件Authenticate
,运行:
php artisan make:middleware Admin/Authenticate
修改handle方法:
<?php
/**
* 用户认证中间件
*/
namespace App\Http\Middleware\Admin;
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $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 \Illuminate\Http\Request $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 App\Providers;
use Illuminate\Support\ServiceProvider;
class AdminServiceProvider extends ServiceProvider
{
/**
* 路由中间件
* @var array
*/
protected $routeMiddleware = [
'admin.auth' => \App\Http\Middleware\Admin\Authenticate::class,
'admin.pjax' => \Spatie\Pjax\Middleware\FilterIfPjax::class,
'admin.log' => \App\Http\Middleware\Admin\LogOperation::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' => [
...,
App\Providers\AdminServiceProvider::class,
]
'aliases' => [
...,
'Admin' => App\Facades\Admin\Admin::class,
]
创建登录表单验证类,运行:
php artisan make:request AdministratorLoginRequest
重写其父类rules
及messages
方法:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
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 App\Http\Controllers\Admin\Auth;
use App\Http\Requests\AdministratorLoginRequest;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* 登录表单
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
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 \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
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 \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
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 App\Http\Controllers\Admin\Home;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
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 Illuminate\Routing\Router
Route::group([
'prefix' => config('admin.route.prefix'),
'namespace' => config('admin.route.namespace'),
'middleware' => config('admin.route.middleware'),
], function (Router $router) {
$router->get('/', 'Home\HomeController@index');
$router->get('login', 'Auth\LoginController@getLoginForm');
$router->post('login', 'Auth\LoginController@postLogin');
$router->post('logout', 'Auth\LoginController@postLogout');
});
数据表迁移与填充: 修改database/seeds/DatabaseSeeder
<?php
use Illuminate\Database\Seeder;
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 \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->forget('uri.intented');
return redirect('/');
}
至此,后台用户登录全部完成。enjoy it!