• Laravel 中的多组认证模式


    在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 IlluminateFoundationAuthUser as Authenticatable;
    
    class Admin extends Authenticatable
    {
        
    }

    否则会报错:

    Argument 1 passed to IlluminateAuthEloquentUserProvider::validateCredentials() must be an instance of IlluminateContractsAuthAuthenticatable

    最主要的就是看看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' => AppUser::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' => AppUser::class,
            ],
            
            // For admin
            'admins' => [
                'driver' => 'eloquent',
                'model' => AppAdmin::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 AppHttpMiddleware;
    
    use Closure;
    use IlluminateSupportFacadesAuth;
    
    class RedirectIfNotAdmin
    {
        /**
         * Handle an incoming request.
         *
         * @param  IlluminateHttpRequest  $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 = [
            IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode::class,
            IlluminateSessionMiddlewareStartSession::class,
            IlluminateViewMiddlewareShareErrorsFromSession::class,
        ];
    
    
    protected $middlewareGroups = [
            'web' => [
                AppHttpMiddlewareEncryptCookies::class,
                IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
                //IlluminateSessionMiddlewareStartSession::class,
                //IlluminateViewMiddlewareShareErrorsFromSession::class,
                AppHttpMiddlewareVerifyCsrfToken::class,
            ],
            
            'api' => [
                'throttle:60,1',
            ],
        ];
    
    
    protected $routeMiddleware = [
            'auth' => AppHttpMiddlewareAuthenticate::class,
            'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
            'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class,
            'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class,
            'admin' => AppHttpMiddlewareRedirectIfNotAdmin::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 AppHttpControllersAdminauth;
    
    use AppAdmin;
    use Validator;
    use AppHttpControllersController;
    use IlluminateFoundationAuthThrottlesLogins;
    use IlluminateFoundationAuthAuthenticatesAndRegistersUsers;
    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 AppHttpControllersAdmin;
    
    
    use IlluminateHttpRequest;
    use IlluminateRoutingController;
    
    use Auth;
    use AppAdmin;
    
    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','AdminauthAuthController@showLoginForm');
    Route::post('/admin/login','AdminauthAuthController@login');
    Route::get('/admin/password/reset','AdminauthPasswordController@resetPassword');
    // Registration Routes...
    Route::get('admin/register', 'AdminauthAuthController@showRegistrationForm');
    Route::post('admin/register', 'AdminauthAuthController@register');


    Route
    ::group(['middleware' => 'web'], function () {
      Route
    ::auth();
      Route
    ::get('/home', 'HomeController@index');
      Route::group(['middleware' => ['admin']], function () {
        //Login Routes...
        Route::get('/admin/logout','AdminauthAuthController@logout');

        Route::get('/admin', 'AdminAdminuser@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()
  • 相关阅读:
    如何:使用向导来处理项目模板 【转载】
    .NET : 如何在生成XML文档时绑定样式表
    如何在生产环境部署K2的流程
    SQL Server 数据库文档生成工具开源项目【合作邀请】
    新的纪元
    SharePoint : 谁说WSS不支持审核
    C++ : 类型的别名和对象的别名
    C++: 引用和地址运算符
    Infopath : 如何通过代码复制格式文本框的值
    正确地使用投影仪和移动硬盘
  • 原文地址:https://www.cnblogs.com/xiaoxiaff/p/5331229.html
Copyright © 2020-2023  润新知