如何使用 laravel 6 在我的包中使用 auth 进行自定义防护?

Posted

技术标签:

【中文标题】如何使用 laravel 6 在我的包中使用 auth 进行自定义防护?【英文标题】:How can I use auth for custom guard in my package using laravel 6? 【发布时间】:2020-05-23 08:02:15 【问题描述】:

我正在尝试使用 admins 表通过 laravel 包进行身份验证。在项目目录中我将adminguard 添加到config/auth.php

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

并且在保护数组中

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],

        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
    ],

以下是我在 pacakge 中的登录控制器

class LoginController extends Controller


   use AuthenticatesUsers;
   protected $redirectTo = '/admin/dashboard';
   protected function redirectTo()
   
         return '/admin/dashboard';
   

   public function __construct()
   
       $this->middleware('guest')->except('logout');
   
   public function login(Request $request)
      
       if(Auth::guard('admin')->attempt($request->only('email','password'), true))
           return redirect()
               ->intended(route('dashboard'))
               ->with('status','You are Logged in as Admin!');
       
   



下面是我的仪表板控制器

class DashboardController extends Controller

    public function __construct()
    
        /* dd(Auth::check()); */ //return false : just want to show you

          $this->middleware('auth:admin');
    

    public function index()
    
        return view('xyz::dashboard');
    


在我的Admin.php 模型中,有以下脚本

namespace App;

class Admin extends \ABC\xyz\App\Models\Admin



这是扩展包模型

namespace ABC\xyz\App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable


    protected $table = 'admins';

以下是我的包裹中的路线

    $namespace = 'ABC\Xyz\App\Http\Controllers';
    Route::group([    
    'namespace' => $namespace,
    'middleware' => ['web'], 
    'prefix' => 'admin'
], function () 
    Route::get('login', function()
        return view('xyz::auth.login');
    )->name('login');

    Route::post('/login', 'Auth\LoginController@login')->name('customLogin');
);

Route::group(['namespace' => $namespace,'prefix' => 'admin',  'middleware' => ['auth']  ], function () 
    Route::get('dashboard', 'DashboardController@index')->name('dashboard');
);

当我尝试登录时,在提交有效详细信息后它不会将我重定向到仪表板,什么也没有发生。此外,当我尝试强制打开 /dashboard 时,它会带我进入登录页面。

在我尝试登录尝试Auth::check() 之后,它也返回true,但在dashboardController.php 构造函数中返回false。以同样的方式Auth::guard('admin')->user() 返回用户信息,而在dashboardController.php 上返回null。我不知道我遗漏了什么以及在哪里遗漏了一些东西。

我想请您指导我。我会很感激的。

谢谢

【问题讨论】:

不需要在app\Http\kernel.php注册中间件组吗?和网络一样吗? @danish-khan-我不这么认为 Auth::user() 返回什么。它返回一个Admin 实例?开发包的另一个重要注意事项:将警卫、提供者或其他东西的配置保留在包内,但可由开发人员更改。还要使用与您的包相关的名称mypackage_admin。开发人员可能已经配置了admin 保护。 你的 AuthServiceProvider 呢,你注册了守卫吗? 【参考方案1】:

当您使用前缀定义路由时,路由名称将类似于 prefix.name,而 url 将类似于 prefix/url。所以在这里你可以试试这个

Route::group([    
        'namespace' => $namespace,
        'middleware' => ['web'], 
        'prefix' => 'admin'
    ], function () 
        Route::get('login', function()
            return view('xyz::auth.login');
        )->name('login');

        Route::post('login', 'Auth\LoginController@login')->name('tryForLogin');
);

Route::group(['namespace' => $namespace,'prefix' => 'admin','middleware' => 'auth'], function () 
    Route::get('dashboard', function()
        return view('xyz::dashboard');
    )->name('dashboard');
);

所有组都以“admin”为前缀,但是登录时可以访问一些路由或页面。

【讨论】:

它给了我一个错误Route [admin.dashboard] not defined. 我现在看到了,这是因为您在 Web 中间件中放置了另一个进行身份验证的组。我会编辑答案,你可以试试我的方法。 它不起作用,再次返回仪表板路线 每次更改路线后使用php artisan optimize。要检查您是否定义了路线,请使用php artisan route:list。它可能有一个错误的定义名称。【参考方案2】:

prefix 是用于定义路由端点前缀的选项。您正在寻找as 选项。

// gives you routes:
// GET /admin/login named "admin.login" with middleware "web"
// POST /admin/login named "admin.tryForLogin" with middleware "web"
Route::group([    
        'namespace' => $namespace,
        'middleware' => ['web'], 
        'prefix' => 'admin',
        'as' => 'admin.'
    ], function () 
        Route::get('login', function() 
            return view('xyz::auth.login');
        )
        ->name('login');

        Route::post('login', 'Auth\LoginController@login')->name('tryForLogin');
    
);

// gives you routes:
// GET /admin/dashboard named "admin.dashboard" with middleware "auth"
Route::middleware(['auth'])->group(function () 
    Route::get('/admin/dashboard', function()
        return view('xyz::dashboard');
    )
    ->name('admin.dashboard');
);

代码更改后运行php artisan optimize:clear

【讨论】:

【参考方案3】:

guest 中间件 (\App\Http\Middleware\RedirectIfAuthenticated) 负责重定向经过身份验证的用户。

当使用中间件时,你必须向它传递身份验证保护,这样才能使用:

guest:guard

示例:在 LoginController 构造函数中,使用

$this->middleware('guest:admin')->except('logout');

而不是$this->middleware('guest')->except('logout');

【讨论】:

以上是关于如何使用 laravel 6 在我的包中使用 auth 进行自定义防护?的主要内容,如果未能解决你的问题,请参考以下文章

在我的 laravel 包中使用其他包[关闭]

将迁移放在 Laravel 5.1 包中的啥位置?

如何在 Laravel 外部的包中使用 Laravel 外观(缓存、日志、存储)

在我的包中使用例如 ddply 时,如何摆脱 R CMD 检查生成的注释?

你如何从 Laravel 的包中扩展视图?

Symfony 3.4 在我的包中使用视图