Laravel 中的多组认证模式

梦想与她 提交于 2020-01-30 00:51:21

在Laravel中,自带的认证能够很方便的对用户进行认证,注册,密码重置等功能。但是在5.2之前都只支持单一用户组。在5.2后,可以为admin和user分别设置不同的认证系统。这样就可以用admin认证admin页面,用user认证user页面。

 

首先需要User和Admin两个表和两个Model,建立过程不阐述,但是记得在Admin的迁移文件中加入:

$table->string('password', 60);
$table->rememberToken();

密码要求最少长度为60。默认为255。如果需要应用能够记得用户登录,还需要加入rememberToken,默认长度为100。

我们还需要将Admin的Model类的基类替换为Authenticatable :

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    
}

否则会报错:

Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable

最主要的就是看看auth.php文件,这里有所有的配置:

<?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,
        ],
 
    ],
 
];

defaults – 默认的登录系统,这里表示用web作为Guard模式,Guard模式定义如下.

guards – Guard定义每个请求如何被授权。我们可以用session或者tokens来处理授权。我们可以看到web数组,定义了User使用session进行授权过程,并且用名为user的provider进行授权。

providers – providers定义了我们使用哪个driver和model进行授权。在这里我们使用User model的eloquent方式。同时你也可以选择数据库或者任何你自己实现的driver。 

passwords – password域主要定义了如何处理密码重置,对于用户Guard方式,使用users作为provider并且使用password_resetstable。 

接下来我们需要添加admin的验证逻辑:

<?php
 
return [
 
    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],
 
    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],
 
        'api' => [
            'driver'   => 'token',
            'provider' => 'users',
        ],
        
        // For admin
        'admins' => [
            'driver'   => 'session',
            'provider' => 'admins'
        ]
    ],
 
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
        
        // For admin
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class
        ]
    ],
 
    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
        'admins' => [
            'provider' => 'admins',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],
 
];

接下来我们在admin的Model中加入guard声明(按照文档中说明应该在app/Http/Controllers/AuthController中添加此句,但是我在Model中添加无问题):

protected $guard = "admins";

之后通过artisan命令即可完成认证逻辑并自动创建对应View:

$ php artisan make:auth

要让admin用户有独立的认证过程,还需要定义属于admin的中间件MiddleWare,否则登陆认证或登陆失败的返回都会根据User认证方式进行。所以新建app/Http/Middleware/RedirectIfNotAdmin.php如下:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfNotAdmin
{
    /**
     * 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 = 'admins')
    {
        if (!Auth::guard($guard)->check()) {
            return redirect('/admin/login');
        }
    
        return $next($request);
    }
}

还需要在app/kernel.php中声明新的middleware:

protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    ];


protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            //\Illuminate\Session\Middleware\StartSession::class,
            //\Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
        ],
        
        'api' => [
            'throttle:60,1',
        ],
    ];


protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'admin' => \App\Http\Middleware\RedirectIfNotAdmin::class,
    ];

Create a new folder Http/Controller/Adminauth and copy the files from Http/Controller/Auth folder

在Http/Controller下创建新的Adminauth文件夹,并将Http/Controller/Auth下的文件复制过来,做必要的修改:

<?php

namespace App\Http\Controllers\Adminauth;

use App\Admin;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Auth;

class AuthController extends Controller
{
    use AuthenticatesAndRegistersUsers, ThrottlesLogins;

    protected $redirectTo = '/admin';
    protected $guard = 'admins';
    
    public function showLoginForm()
    {
        if (Auth::guard('admins')->check())
        {
            return redirect('/admin');
        }
        
        return view('admin.auth.login');
    }
    
    public function showRegistrationForm()
    {
        return view('admin.auth.register');
    }
    
    public function resetPassword()
    {
        return view('admin.auth.passwords.email');
    }
    
    public function logout(){
        Auth::guard('admins')->logout();
        return redirect('/admin/login');
    }
}

创建一个新的文件夹Http/Controller/Admin,并将Http/Controller下的Controller.php复制进新建的Admin文件夹。

创建新文件Http/Controller/Admin/Adminuser.php:

<?php

namespace App\Http\Controllers\Admin;


use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

use Auth;
use App\Admin;

class Adminuser extends Controller
{
    public function __construct(){
        $this->middleware('admin');
   }
    
    public function index(){
        return view('admin.home');
    }
}

接下来就是view界面。新建文件夹resources/views/admin,并将resources/views/auth, resources/views/layouts & resources/views/home.blade.php复制进去。在复制的这些文件里修改路径变为:

@extends('admin.layouts.app')

Router文件:

<?php
Route::get('/', function () {
    return view('welcome');
});

Route::get('/admin/login','Adminauth\AuthController@showLoginForm');
Route::post('/admin/login','Adminauth\AuthController@login');
Route::get('/admin/password/reset','Adminauth\PasswordController@resetPassword');
// Registration Routes...
Route::get('admin/register', 'Adminauth\AuthController@showRegistrationForm');
Route::post('admin/register', 'Adminauth\AuthController@register');
 Route::group(['middleware' => 'web'], function () {   Route::auth();   Route::get('/home', 'HomeController@index');   Route::group(['middleware' => ['admin']], function () {     //Login Routes...     Route::get('/admin/logout','Adminauth\AuthController@logout');    Route::get('/admin', 'Admin\Adminuser@index');   });});

成功后可以通过guard方式访问不同的认证逻辑:

// By using auth helper function 
 
auth()->guard('admins')->attempt(['email' => '', 'password' => ''])
 
// or using Facade
 
Auth::guard('admins')->attempt(['email' => '', 'password' => ''])
 
// To get authenticated admin
 
auth()->guard('admins')->user()
 
// To check whether admin is logged in or not 
 
auth()->guard('admins')->check()

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!