【问题标题】:Custom multi-auth guard logging & routing自定义多身份验证保护日志记录和路由
【发布时间】:2019-12-30 12:57:02
【问题描述】:

我正在开发一个有 4 个不同用户的 Laravel 6 应用程序(每个用户都有不同的表)。为此,我使用了多重身份验证防护,并按照本教程在线创建了我的第一个防护 (https://pusher.com/tutorials/multiple-authentication-guards-laravel)。

这是我的自定义守卫“学生”

    'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],
    'student' => [
        'driver' => 'session',
        'provider' => 'students',
    ],
],

和提供者

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

我有一个使用名为“学生”的自定义身份验证保护的自定义登录控制器

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Auth;
use Student;

class LoginController extends Controller
{
    protected $redirectTo = '/dashboard';

    public function __construct()
    {
        $this->middleware('guest')->except('destroy');
        $this->middleware('student')->except('destroy');
    }
    public function studentLogin(Request $request)
    {
        $this->validate($request, [
            'email'   => 'required|email',
            'password' => 'required|min:5'
        ]);

        if (Auth::guard('student')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {

            return redirect()->intended('admin/home')->with('smessage', 'Logged in successfully...!');
        }
        return back()->withInput($request->only('email', 'remember'));
    }...
    }

现在,每当我尝试登录时,似乎我已登录并重定向到中间件/RedirectIfAuthenticated.php 中定义的 URL,但弹出此错误“尝试获取非对象的属性”来自在auth()->user() 上没有可用登录用户数据的通用标题模板。

如果我使用'middleware'=>'auth:student',我可以作为学生访问路线并通过auth()->user() 获取记录的用户数据。管理员使用'middleware'=>'auth' 相同,但将authauth:student 作为数组传递我无法通过auth()->user() 为两个用户获取记录的用户数据。

这是我的路线:

Route::get('/', function () {
    return view('welcome');
});
Route::get('/login', 'LoginController@create')->name('login');
Route::post('login', 'LoginController@store');
Route::get('/login/student', 'LoginController@create')->name('studentlogin');
Route::post('/login/student', 'LoginController@studentLogin');

Route::get('/logout', 'LoginController@destroy')->name('logout'); 

Route::group(['prefix'=>'admin', 'namespace' => 'Dashboard', 'middleware'=> 'auth' ], function () {

    Route::get('home', 'DashboardController@display')->name('admin.home');

    Route::get('users', 'UserlistController@display')->name('admin.userlist');
    Route::post('users', 'UserlistController@store')->name('admin.create');
    Route::delete('users/{id}', 'UserlistController@destroy')->name('admin.deleteuser');

});

Route::group(['prefix'=>'student', 'namespace' => 'Students', 'middleware'=> 'auth:student' ], function () {
    Route::get('all', 'StudentsController@display')->name('student.all');
    Route::delete('all/{id}', 'StudentsController@destroy')->name('student.delete');
    Route::post('all', 'StudentsController@store')->name('student.store');
});

在 StackOverflow 上找不到其他相关主题的任何解决方案。如果我在某处有任何错误,请纠正我,或者如果您想检查任何其他文件的代码,请告诉我。

提前致谢。

【问题讨论】:

  • 试试视频教程youtube.com/…
  • 您能否发布您在身份验证后尝试访问的路由的完整路由定义?另请注意,您将以学生身份登录的用户重定向到admin/home,而不是RedirectIfAuthenticated 中间件中定义的路由。
  • @arun 我也看过上面提到的视频,我相信我已经完成了上面提到的所有步骤。
  • @matteo-meil 虽然重定向从 loginController 设置为“admin/home”,但我仍然被重定向到我在 redirectIfAutnenticated.php 中定义的内容,即“student/all”。有没有错误?附言我也将我的路线定义添加到问题中

标签: php laravel laravel-5 laravel-6


【解决方案1】:

您在 auth()->user() 上没有任何数据,因为您正在查询默认保护,即 web

如果你想通过studentguard检索登录的用户,你必须做auth()->guard('student')->user();

还记得每次将你的守卫传递给auth 和使用auth 的中间件。

即:如果您需要将某些路由仅限于经过身份验证的用户,您需要这样做:

Route::group(['middleware' => 'auth:student'], function() {
    // Your restricted routes
})

省略:student 将一如既往地使用默认的web 保护

请注意,如果您需要将路由限制为属于不同守卫的用户,您可以将这些守卫传递给auth

Route::group(['middleware' => 'auth:web,student'], function() {
    // Your restricted routes
}];

这样,Laravel 将同时检查 webstudent 保护,并自动设置属于经过身份验证的用户的保护。您还可以通过 auth()->user() 忘记通过正确的守卫来检索您的用户

【讨论】:

  • 好的,我已经为路由组学生添加了中间件 ['middleware' => 'auth:student']。每当我应用此中间件时,它都适用于该路线,即我在 auth()->user() 和 auth()->guard('student')->user(); 上都收到登录用户的数据;关于学生相关路线 太好了!但是为什么我不能访问我没有应用任何中间件的路由或路由组(因为它们是任何用户都可以访问的公共页面)?
  • 因为'middleware'=> 'auth' 在路由定义中(检查您的路由定义)。正如我在回答中所写,这些路由将使用默认的web 保护。如果您不指定任何中间件,则访问该路由不会有任何问题,但如果分配错误的中间件,您将无法访问它
  • 感谢您的澄清,但是:1. 我没有通过 auth()->user() 在没有定义中间件的路由上获取登录用户的数据 2. 我尝试添加 'middleware'=> ['auth', 'auth:student'] 但甚至不能从管理员和学生用户访问路由。我又做错什么了吗?
  • 在没有中间件的路由中,您必须使用auth()->guard('student')->user(),正如我在答案中所写。在带有middleware'=> ['auth', 'auth:student'] 的路由中,您必须删除auth 并只留下auth:student。请注意,中间件是按照您编写它们的顺序执行的。你应该仔细阅读middlewares docs
  • 很少有其他用户和他们的中间件使用与auth()->user()相同的模板,所以我不能只使用auth()->guard('student')->user()。与路由中的中间件相同,仅使用 auth:student 将只允许学生访问,而我希望它在某些情况下被多个用户或所有用户访问。最好的方法是什么?
猜你喜欢
  • 2021-12-16
  • 2020-05-10
  • 2021-07-31
  • 2021-11-07
  • 2019-11-19
  • 2013-12-11
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多