2016年10月21日 星期五

Laravel 5.3 多用户表登录

Laravl5.3多用户表登录
关于Laravel5.2多用户表登录文章传送门:http://iwanli.me/article/42

简介#

在底层代码中,Laravel 的认证组件由 guards 和 providers组成,Guard 定义了用户在每个请求中如何实现认证,例如,Laravel 通过 session guard来维护 Session 存储的状态、Cookie 以及 token guard,token guard 是认证用户发送请求时带的API token。
Provider 定义了如何从持久化存储中获取用户信息,Laravel 底层支持通过 Eloquent 和数据库查询构建器两种方式来获取用户,如果需要的话,你还可以定义额外的 Provider
相对于Laravel5.2而言,Laravel5.3在底层代码中做了很多修改,方法更加简洁,这个下面会提到。虽然代码改了很多,但是原理都是一样的,我们只需要重写不同的方法而已。

默认认证#

首先我们使用Laravel 5.3提供的开箱即用的认证:
php artisan make:auth
该Artisan命令会生成用户认证所需的路由、视图以及HomeController:
认证的路由也一并生成好了,查看路由文件routes/web.php,会发现该文件已经被更新:
Auth::routes();

Route::get('/home', 'HomeController@index');
其中Auth::routes()定义了登录注册及找回密码路由,/home 为用户认证成功后跳转的路由。

验证#

接下来我们先实现前台用户登录,也就是Laravel自带的Users用户表登录。通过生成的默认登录认证,已经写好了所有代码,剩下要做的就是使用迁移命令创建用户认证相关表:
php artisan migrate
执行命令后会生成 users 表和 password_resets 表,分别为用户表和密码重置表。然后我们就可以在浏览器中输入http://blog.me/register来注册新用户:
我们创建一个 iwanli 的用户,注册成功后直接跳转 /home,并且刚注册的用户名也已经显示出来了:
登录、找回密码功能都已经写好,我就不一一测试了~

自定义用户表登录#

首先要看看默认的用户认证配置文件auth.php,配置如下:

return [
    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
    ],
    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
           'expire' => 60,
        ],
    ],
];
认证是由 guard 和 provider 两部分构成的(参考用户认证文档),defaults 配置是选择哪一个 guard 认证驱动,所以我们在这两个配置项中分别添加一个 admin 和 admins 选项。

return [
    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ],
    ],
    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
           'expire' => 60,
        ],
    ],
];
创建后台用户用户表及Model
接下来我们来实现后台用户登录,使用如下Artisan命令生成后台用户Model:
php artisan make:model Models/Admin -m
带上-m 选项会生成对应迁移文件 *_create_admins_table,我们定义该数据表字段和users一样,你也可以自定义:


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('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('admins');
    }
}
由于后台一般只需要登录功能,所以来给 admins 表填充一些数据:
php artisan make:seeder AdminsTableSeeder
执行完命令后将会在 database/seeds 目录下生成 AdminsTableSeeder.php 文件。接下来我们定义一个数据模型工厂,在  database/factories/ModelFactory.php 中添加如下代码:


/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/

$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

$factory->define(App\Models\Admin::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});
模型工厂定义完成后,在 AdminsTableSeeder.php 中填充数据:


use Illuminate\Database\Seeder;

class AdminsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory('App\Models\Admin',3)->create([
            'password' => bcrypt('123456')
            ]);
    }
}
填充数据弄好后,在 DatabaseSeeder.php 中加入 AdminsTableSeeder 类


use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
        $this->call(AdminsTableSeeder::class);
    }
}
最后执行迁移命令:
php artisan migrate --seed
OK,我们在查看数据库:
修改Admin模型类如下:


namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin 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',
    ];
}
后台用户认证路由及控制器
使用Artisan命令创建控制器:
php artisan make:controller Admin/LgoinController 
php artisan make:controller Admin/DashboardController
编辑 Admin/LoginController.php ,代码如下:

namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
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 / registration.
     *
     * @var string
     */
    protected $redirectTo = '/admin/dash';
    protected $username;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest:admin', ['except' => 'logout']);
        $this->username = config('admin.global.username');
    }
    /**
     * 重写登录视图页面
     * @author 晚黎
     * @date   2016-09-05T23:06:16+0800
     * @return [type]                   [description]
     */
    public function showLoginForm()
    {
        return view('admin.login.index');
    }
    /**
     * 自定义认证驱动
     * @author 晚黎
     * @date   2016-09-05T23:53:07+0800
     * @return [type]                   [description]
     */
    protected function guard()
    {
        return auth()->guard('admin');
    }
}
在 LoginController 中我们在构造函数中修改了 guest 中间件,用来跳转不同路由:
  • app\Http\Middleware\RedirectIfAuthenticated.php


namespace App\Http\Middleware;

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)
    {
        if (Auth::guard($guard)->check()) {
            // 根据不同 guard 跳转到不同的页面
            $url = $guard ? 'admin/dash':'/home';
            return redirect($url);
        }

        return $next($request);
    }
}
编辑 Admin/DashboardController.php ,代码如下:


namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class DashboardController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth.admin:admin');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        dd('后台首页,当前用户名:'.auth('admin')->user()->name);
    }
}
在 DashboardController 构造函数中我们添加了一个 auth.admin Middleware,这个是我们自定义的,所以我们要来新建一个 Middleware
php artisan make:middleware AdminAuthMiddleware
编辑 AdminAuthMiddleware :


namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class AdminAuthMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next,$guard = null)
    {
        if (Auth::guard($guard)->guest()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('admin/login');
            }
        }
        return $next($request);
    }
}
在 app\Http\Kernel.php 中注册:
protected $routeMiddleware = [
    ......
    'auth.admin' => \App\Http\Middleware\AdminAuthMiddleware::class,
    ......
];
在 routes/web.php 中添加如下路由:
Route::group(['prefix' => 'admin','namespace' => 'Admin'],function ($router)
{
    $router->get('login', 'LoginController@showLoginForm')->name('admin.login');
    $router->post('login', 'LoginController@login');
    $router->post('logout', 'LoginController@logout');

    $router->get('dash', 'DashboardController@index');
});
视图文件创建及修改
最后我们要创建后台用户认证对应视图文件,这里我们简单复制默认用户视图模板并稍作修改即可,复制 resources\views\auth\login.blade.php 文件到并重命名 resources\views\admin\login\index.blade.php 。
修改resources\views\admin\login\index.blade.php目录下登录及注册表单提交地址:
{{ url('/login') }} -> {{ route('admin.login') }}
OK,在浏览器中访问http://blog.me/admin/login 测试:
点击login,页面跳转到http://blog.me/admin/dash,说明后台登录成功!
OK,至此我们已经完成前后台用户同时登录认证功能。 Enjoy it !
更多关于Laravel的文章请关注我的博客:http://www.iwanli.me

from : https://laravel-china.org/topics/2777

沒有留言:

wibiya widget