Laravel 5.3 使用内置的 Auth 组件实现多用户认证功能以及登陆才能访问后台的功能的一种实现方法
在开发中,我们经常会遇到多种类型的用户的认证问题,比如后台的管理员和前台的普通用户。Laravel 5.3 内置的 Auth 组件已经能很好的满足这项需求,下面大概记录下使用方法。
另外,后台页面常常需要登录才能访问,为了完成类似的功能,大家一般都习惯创建新的中间件来实现。但是 Auth 组件已经存在类似的中间件,我们可以在已有的基础上进行完善,具体请看 后台认证
-> 登陆才能访问后台的功能的一种实现方法
。
注意:这里我们只考虑管理员和普通用户存放在不同的表中的情况
创建项目 E:PhpStormProjects>composer create-project --prefer-dist laravel/laravel blog
进入项目 E:PhpStormProjects>cd blog
运行项目 E:PhpStormProjectslog>php arstisan serve
看看效果 浏览器访问http://localhost:8000
数据库配置 .env
中配置 DB 相关选项即可
数据库迁移 E:PhpStormProjectslog>php artisan migrate
生成 Auth E:PhpStormProjectslog>php artisan make:auth
该命令应该在新安装的应用下使用,它会生成 layout 布局视图,注册和登录视图,以及所有的认证路由,同时生成 HomeController ,用来处理登录成功后会跳转到该控制器下的请求。
浏览器访问 http://localhost:8000
我们看到右上角多了 LOGIN 和 REGISTER 的链接,我们可以试着注册和登陆。
至此,前台认证完成。
后台首页显示
生成后台首页控制器 E:PhpStormProjectslog>php artisan make:controller Admin/IndexController
建立后台首页的视图 resources/views/admin/index.blade.php
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>首页 | 后台系统</title>
</head>
<body>
<h3>首页</h3>
</body>
</html>
后台首页控制器 app/Http/Controllers/Admin/IndexController.php
添加方法
public function index()
{
return view("admin/index");
}
路由文件 routes/web.php
添加路由组
Route::group(["prefix" => "admin"], function () {
Route::get("/", "AdminIndexController@index");
});
浏览器访问 http://localhost:8000/admin
可看到后台首页
后台首页显示完成
管理员数据表生成、数据表模型建立以及数据表填充
生成管理员数据表迁移文件 E:PhpStormProjectslog>php artisan make:migration create_administrators_table
修改 database/migrations/*_create_administrators_table.php
中的 up() 与 down() 方法
public function up()
{
Schema::create("administrators", function (Blueprint $table) {
$table->increments("id");
$table->string("name");
$table->string("email")->unique();
$table->string("password");
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::drop("administrators");
}
生成数据表 E:PhpStormProjectslog>php artisan migrate
至此,数据表建立
生成数据表模型 E:PhpStormProjectslog>php artisan make:model Models/Administrator
修改 app/Models/Administrator.php
<?php
namespace AppModels;
use IlluminateNotificationsNotifiable;
use IlluminateFoundationAuthUser as Authenticatable;
class Administrator 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",
];
}
提示:该模型根据app/User.php
修改
至此数据表模型建立完成
生成数据表填充文件 E:PhpStormProjectslog>php artisan make:seeder AdministratorsTableSeeder
database/factories/ModelFactory.php
中添加
$factory->define(AppModelsAdministrator::class, function (FakerGenerator $faker) {
static $password;
return [
"name" => $faker->name,
"email" => $faker->unique()->safeEmail,
"password" => $password ?: $password = bcrypt("secret"),
"remember_token" => str_random(10),
];
});
修改 database/seeds/AdministratorsTableSeeder.php
中的 run() 方法
public function run()
{
factory(AppModelsAdministrator::class, 3)->create([
"password" => bcrypt("040313"),
]);
}
修改 database/seeds/DatabaseSeeder.php
中的 run() 方法
public function run()
{
$this->call(AdministratorsTableSeeder::class);
}
数据表填充 E:PhpStormProjectslog>php artisan db:seed
至此,数据表填充完成,在 administrators 中可看到 3 条样例数据
管理员登陆页面显示
新建 app/Http/Controllers/Admin/Auth/LoginController.php
<?php
namespace AppHttpControllersAdminAuth;
use AppHttpControllersController;
use IlluminateFoundationAuthAuthenticatesUsers;
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.
*
* @var string
*/
protected $redirectTo = "/admin";
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware("guest", ["except" => "logout"]);
}
/**
* 重写 Show the application"s login form.
*
* @return IlluminateHttpResponse
*/
public function showLoginForm()
{
return view("admin/auth/login");
}
}
提示:该控制器内容根据 app/Http/Controllers/Auth/LoginController.php
修改
新建 resources/views/admin/Auth/login.blade.php
,复制 resources/views/auth/login.blade.php
的内容到这个文件即可
注意:不要忘了修改登陆表单的 action
地址为 {{ url("/admin/login") }}
修改路由组
Route::group(["prefix" => "admin"], function () {
Route::get("login", "AdminAuthLoginController@showLoginForm");
Route::get("/", "AdminIndexController@index");
});
至此,后台登陆页面显示完成。访问 http://localhost:8000/admin/login
可看到对应页面
管理员认证
修改 config/auth.php
,在键为 guards
和 providers
的数组中添加管理员相关信息
"guards" => [
"web" => [
"driver" => "session",
"provider" => "users",
],
"api" => [
"driver" => "token",
"provider" => "users",
],
"admin" => [
"driver" => "session",
"provider" => "administrators",
],
],
"providers" => [
"users" => [
"driver" => "eloquent",
"model" => AppUser::class,
],
// "users" => [
// "driver" => "database",
// "table" => "users",
// ],
"administrators" => [
"driver" => "eloquent",
"model" => AppModelsAdministrator::class,
],
],
修改 app/Http/Controllers/Admin/Auth/LoginController.php
<?php
namespace AppHttpControllersAdminAuth;
use AppHttpControllersController;
use IlluminateFoundationAuthAuthenticatesUsers;
use IlluminateHttpRequest;
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.
*
* @var string
*/
protected $redirectTo = "/admin";
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware("guest:admin", ["except" => "logout"]);
}
/**
* 重写 Show the application"s login form.
*
* @return IlluminateHttpResponse
*/
public function showLoginForm()
{
return view("admin/auth/login");
}
/**
* 重写 Get the guard to be used during authentication.
*
* @return IlluminateContractsAuthStatefulGuard
*/
protected function guard()
{
return Auth::guard("admin");
}
/**
* 重写 Log the user out of the application.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->flush();
$request->session()->regenerate();
return redirect("/admin/login");
}
}
app/Http/Middleware/RedirectIfAuthenticated.php
即 guest
中间件。它的作用是当请求者请求登陆时,如果已登录则将其跳转到合适页面。如果请求的是后台登陆页面且已登录的话,我们应将其跳转到后台首页,而不是默认的前台首页。修改其中的 handle() 方法
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
$path = $guard? "/admin" : "/home";
return redirect($path);
}
return $next($request);
}
修改路由组
Route::group(["prefix" => "admin"], function () {
Route::get("login", "AdminAuthLoginController@showLoginForm");
Route::post("login", "AdminAuthLoginController@login");
Route::post("logout", "AdminAuthLoginController@logout");
Route::get("/", "AdminIndexController@index");
});
顺便在后台首页添加一个登出链接,修改 resources/views/admin/index.blade.php
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>首页 | 后台系统</title>
</head>
<body>
<h3>首页</h3>
<p>
状态:
@if(Auth::guard("admin")->check())
已登录
<a href="#"
onclick="event.preventDefault();
document.getElementById("logout-form").submit();">
Logout
</a>
<form id="logout-form" action="{{ url("/admin/logout") }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
@else
未登录
@endif
</p>
</body>
</html>
至此,管理员认证(登入与登出)已基本完成。
注意:由于后台很少需要注册功能,所以这部分功能实现不在考虑范围
登陆才能访问后台的功能的一种实现方法
目前的后台认证中,如果管理员没有登录,他也能访问后台首页,这显然是有问题的。这里,可以利用自带的 Auth 系统的 vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php
这个中间件来实现。查看其中的 authenticate() 方法
protected function authenticate(array $guards)
{
if (empty($guards)) {
return $this->auth->authenticate();
}
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}
throw new AuthenticationException("Unauthenticated.", $guards);
}
如果管理员或者用户没有登录,则会抛出认证异常。我们可以在 app/Exceptions/Handler.php
中处理这个异常,将登陆者转到相应页面。所以我们可以修改这个文件中的 unauthenticated() 方法
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(["error" => "Unauthenticated."], 401);
}
if(in_array("admin", $exception->guards())) {
return redirect()->guest("/admin/login");
}
return redirect()->guest("login");
}
修改路由组
Route::group(["prefix" => "admin"], function () {
Route::get("login", "AdminAuthLoginController@showLoginForm");
Route::post("login", "AdminAuthLoginController@login");
Route::post("logout", "AdminAuthLoginController@logout");
Route::group(["middleware" => "auth:admin"], function () {
Route::get("/", "AdminIndexController@index");
});
});
至此,后台登陆才能访问。
httpd-2.4.23-x64-vc11
php-5.6.24-Win32-VC11-x64
mysql-5.7.14-winx64