Laravel 5.3 使用内置的 Auth 组件实现多用户认证功能以及登陆才能访问后台的功能的一种实现方法

来源:互联网 发布:明星淘宝店铺名称 编辑:程序博客网 时间:2024/06/07 10:08

概述

在开发中,我们经常会遇到多种类型的用户的认证问题,比如后台的管理员和前台的普通用户。Laravel 5.3 内置的 Auth 组件已经能很好的满足这项需求,下面大概记录下使用方法。
另外,后台页面常常需要登录才能访问,为了完成类似的功能,大家一般都习惯创建新的中间件来实现。但是 Auth 组件已经存在类似的中间件,我们可以在已有的基础上进行完善,具体请看 后台认证 -> 登陆才能访问后台的功能的一种实现方法
注意:这里我们只考虑管理员和普通用户存放在不同的表中的情况

创建项目

创建项目 E:\PhpStormProjects>composer create-project --prefer-dist laravel/laravel blog
进入项目 E:\PhpStormProjects>cd blog
运行项目 E:\PhpStormProjects\blog>php arstisan serve
看看效果 浏览器访问http://localhost:8000

项目配置

数据库配置 .env 中配置 DB 相关选项即可

前台认证

数据库迁移 E:\PhpStormProjects\blog>php artisan migrate
生成 Auth E:\PhpStormProjects\blog>php artisan make:auth

该命令应该在新安装的应用下使用,它会生成 layout 布局视图,注册和登录视图,以及所有的认证路由,同时生成 HomeController ,用来处理登录成功后会跳转到该控制器下的请求。

浏览器访问 http://localhost:8000
我们看到右上角多了 LOGIN 和 REGISTER 的链接,我们可以试着注册和登陆。
至此,前台认证完成。

后台认证

后台首页显示

生成后台首页控制器 E:\PhpStormProjects\blog>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('/', 'Admin\IndexController@index');});

浏览器访问 http://localhost:8000/admin 可看到后台首页
后台首页显示完成

管理员数据表生成、数据表模型建立以及数据表填充

生成管理员数据表迁移文件 E:\PhpStormProjects\blog>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:\PhpStormProjects\blog>php artisan migrate
至此,数据表建立
生成数据表模型 E:\PhpStormProjects\blog>php artisan make:model Models/Administrator
修改 app/Models/Administrator.php

<?phpnamespace App\Models;use Illuminate\Notifications\Notifiable;use Illuminate\Foundation\Auth\User 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:\PhpStormProjects\blog>php artisan make:seeder AdministratorsTableSeeder
database/factories/ModelFactory.php 中添加

$factory->define(App\Models\Administrator::class, function (Faker\Generator $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(App\Models\Administrator::class, 3)->create([        'password' => bcrypt('040313'),    ]);}

修改 database/seeds/DatabaseSeeder.php 中的 run() 方法

public function run(){    $this->call(AdministratorsTableSeeder::class);}

数据表填充 E:\PhpStormProjects\blog>php artisan db:seed
至此,数据表填充完成,在 administrators 中可看到 3 条样例数据

管理员登陆页面显示

新建 app/Http/Controllers/Admin/Auth/LoginController.php

<?phpnamespace App\Http\Controllers\Admin\Auth;use App\Http\Controllers\Controller;use Illuminate\Foundation\Auth\AuthenticatesUsers;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 \Illuminate\Http\Response     */    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', 'Admin\Auth\LoginController@showLoginForm');    Route::get('/', 'Admin\IndexController@index');});

至此,后台登陆页面显示完成。访问 http://localhost:8000/admin/login 可看到对应页面

管理员认证

修改 config/auth.php ,在键为 guardsproviders 的数组中添加管理员相关信息

'guards' => [    'web' => [        'driver' => 'session',        'provider' => 'users',    ],    'api' => [        'driver' => 'token',        'provider' => 'users',    ],    'admin' => [        'driver' => 'session',        'provider' => 'administrators',    ],],'providers' => [    'users' => [        'driver' => 'eloquent',        'model' => App\User::class,    ],    // 'users' => [    //     'driver' => 'database',    //     'table' => 'users',    // ],    'administrators' => [        'driver' => 'eloquent',        'model' => App\Models\Administrator::class,    ],],

修改 app/Http/Controllers/Admin/Auth/LoginController.php

<?phpnamespace App\Http\Controllers\Admin\Auth;use App\Http\Controllers\Controller;use Illuminate\Foundation\Auth\AuthenticatesUsers;use Illuminate\Http\Request;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 \Illuminate\Http\Response     */    public function showLoginForm()    {        return view('admin/auth/login');    }    /**     * 重写 Get the guard to be used during authentication.     *     * @return \Illuminate\Contracts\Auth\StatefulGuard     */    protected function guard()    {        return \Auth::guard('admin');    }    /**     * 重写 Log the user out of the application.     *     * @param \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    public function logout(Request $request)    {        $this->guard()->logout();        $request->session()->flush();        $request->session()->regenerate();        return redirect('/admin/login');    }}

app/Http/Middleware/RedirectIfAuthenticated.phpguest 中间件。它的作用是当请求者请求登陆时,如果已登录则将其跳转到合适页面。如果请求的是后台登陆页面且已登录的话,我们应将其跳转到后台首页,而不是默认的前台首页。修改其中的 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', 'Admin\Auth\LoginController@showLoginForm');    Route::post('login', 'Admin\Auth\LoginController@login');    Route::post('logout', 'Admin\Auth\LoginController@logout');    Route::get('/', 'Admin\IndexController@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())            已登录&nbsp;            <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', 'Admin\Auth\LoginController@showLoginForm');    Route::post('login', 'Admin\Auth\LoginController@login');    Route::post('logout', 'Admin\Auth\LoginController@logout');    Route::group(['middleware' => 'auth:admin'], function () {        Route::get('/', 'Admin\IndexController@index');    });});

至此,后台登陆才能访问。

测试环境

httpd-2.4.23-x64-vc11php-5.6.24-Win32-VC11-x64mysql-5.7.14-winx64
0 0