当预期行为相同时,为什么通过 `auth guard A` 重定向的登录与来自 `auth guard B` 的登录不同?
Why is a login via `auth guard A` redirected different than one from `auth guard B` when the same behaviour is expected?
首先,我不是 PHP 开发或 Laravel 方面的专业人士,但我会尽力为我解释我的问题。我也尝试提供足够的信息,但是如果缺少某些内容,请让我知道缺少什么,我会添加它!
关于我的项目的一些重要背景:
- Laravel 6.18(如果我的第一个目标达到了会尽快更新)
- 我使用 Hyn/Multi-tenant 让我的应用程序成为多租户。
- 我使用 Vue 前端,我通过
app.js
给 Vue 一个 bearer token
该应用程序应该是一个多租户应用程序,其中每个租户都有自己的用户 table。我首先将所有内容构建为“单一租户”。当基本功能实现并运行良好时,我添加了 Hyn/MT 使其成为多租户,将特定于租户的 table 移动到租户数据库文件夹并更新了模型。现在我知道在构建所有功能之前最好从 Hyn/MT 开始,但到目前为止我一切正常。
在我将多租户支持添加到我的项目并修复损坏的功能后,我决定添加一个特定于管理员的区域来管理租户。为此,我向包含管理员用户的 master
数据库添加了一个 SystemU ser
table。之后,我更新了我的 web.php
,因此它将子域提供给 LoginController.guard()
函数。我的代码:
// web.php
Route::group(array('domain' => '{subdomain}.festipay.xlan'), function () {
Route::post('login', 'Auth\LoginController@login');
});
// LoginController.php
protected function guard()
{
if (Request::route("subdomain") == "admin") {
return Auth::guard('admin_web');
} else {
return Auth::guard('web');
}
}
我也更新了我的config/auth.php
,现在看起来是这样的:
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin_web' => [
'driver' => 'session',
'provider' => 'admin_users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admin_users' => [
'driver' => 'eloquent',
'model' => App\SystemUser::class,
]
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
除了提到的更改外,我还没有实现任何特定于管理的逻辑。所以我希望管理员用户的处理方式完全相同,除了他们的身份验证方式。
例如登录的租户用户tenant_x.domain.com
在登录时重定向到 /dashboard
,在注销时重定向回 /login
。登录 admin.domain.com
的管理员用户在登录成功后不会重定向到 /dashboard
,而是会再次重定向回 /login
。当然这不是预期的行为,因为它应该(当前)与租户用户相同(因此当登录成功时重定向到 /dasboard
)
我认为当我使用有效的管理员凭据和 false
(并且视图显示错误的凭据)时,他们自己的身份验证工作正常,如 LoginController.attemptLogin()
returns true
当我使用无效凭据时。
我在 this post 中发现这可能是一个 session 问题,我尝试应用 post 中提到的解决方案。不幸的是,将 protected $primaryKey = 'id';
添加到 SystemUser
class 并没有解决问题。我还将租户 User
class 与 SystemUser
class 进行了比较,但除了我从 SystemUser
等地址中删除的不重要字段外,它们几乎相同。
我不知道如何找出问题发生的位置或如何解决这个问题。目标是将成功登录的管理员重定向到另一个页面 /dashboard
。有人可以帮我找出问题所在吗?当有人可以帮助我获得与租户当前相同的管理员行为时,我已经很高兴了。
提前致谢!
更新 1 @David Barker
关于 session,我认为了解这一点也很重要:
- I use a Vue front end, i give a
不记名令牌to Vue via the
app.js``
我的 session 配置:
<?php
use Illuminate\Support\Str;
return [
'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION', null),
'table' => 'sessions',
'store' => env('SESSION_STORE', null),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN', null),
'secure' => env('SESSION_SECURE_COOKIE', false),
'http_only' => true,
'same_site' => null,
];
我在LoginController->attemptLogin();
函数中做了一个dd($request->session();)
,结果如下。除了 id
和 _token
之外,两个用户的结果相同。 (在这两种情况下,我都在尝试登录之前清除了 cookie)
Illuminate\Session\Store {#490 ▼
#id: "7WI7JUWPnS4pg3EHvaxk5TOKaM9l9UXJi1zJNKuG"
#name: "festipay_session"
#attributes: array:1 [▼
"_token" => "mtMWanYGMUxFHivOqAaEmVQnHDE0hvwKkHMgCswg"
]
#handler: Illuminate\Session\FileSessionHandler {#489 ▼
#files: Illuminate\Filesystem\Filesystem {#198}
#path: "/var/www/domain.com/storage/framework/sessions"
#minutes: "120"
}
#started: true
}
也许这也是一个有趣的信息。左边是管理员的响应(在我单击 login
按钮后),右边是工作租户登录。
我终于找到问题了。这很容易解决。我没有为 Route::group
指定 auth guard
。
原来是这样的:
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () { return redirect('/dashboard'); });
Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard');
Route::get('/logout', 'Auth\LoginController@logout')->name
我把它改成了这样让它工作:
Route::group(['middleware' => 'auth:system_user_web,web'], function () {
Route::get('/', function () { return redirect('/dashboard'); });
Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard');
Route::get('/logout', 'Auth\LoginController@logout')->name
首先,我不是 PHP 开发或 Laravel 方面的专业人士,但我会尽力为我解释我的问题。我也尝试提供足够的信息,但是如果缺少某些内容,请让我知道缺少什么,我会添加它!
关于我的项目的一些重要背景:
- Laravel 6.18(如果我的第一个目标达到了会尽快更新)
- 我使用 Hyn/Multi-tenant 让我的应用程序成为多租户。
- 我使用 Vue 前端,我通过
app.js
给 Vue 一个
bearer token
该应用程序应该是一个多租户应用程序,其中每个租户都有自己的用户 table。我首先将所有内容构建为“单一租户”。当基本功能实现并运行良好时,我添加了 Hyn/MT 使其成为多租户,将特定于租户的 table 移动到租户数据库文件夹并更新了模型。现在我知道在构建所有功能之前最好从 Hyn/MT 开始,但到目前为止我一切正常。
在我将多租户支持添加到我的项目并修复损坏的功能后,我决定添加一个特定于管理员的区域来管理租户。为此,我向包含管理员用户的 master
数据库添加了一个 SystemU ser
table。之后,我更新了我的 web.php
,因此它将子域提供给 LoginController.guard()
函数。我的代码:
// web.php
Route::group(array('domain' => '{subdomain}.festipay.xlan'), function () {
Route::post('login', 'Auth\LoginController@login');
});
// LoginController.php
protected function guard()
{
if (Request::route("subdomain") == "admin") {
return Auth::guard('admin_web');
} else {
return Auth::guard('web');
}
}
我也更新了我的config/auth.php
,现在看起来是这样的:
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin_web' => [
'driver' => 'session',
'provider' => 'admin_users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admin_users' => [
'driver' => 'eloquent',
'model' => App\SystemUser::class,
]
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
除了提到的更改外,我还没有实现任何特定于管理的逻辑。所以我希望管理员用户的处理方式完全相同,除了他们的身份验证方式。
例如登录的租户用户tenant_x.domain.com
在登录时重定向到 /dashboard
,在注销时重定向回 /login
。登录 admin.domain.com
的管理员用户在登录成功后不会重定向到 /dashboard
,而是会再次重定向回 /login
。当然这不是预期的行为,因为它应该(当前)与租户用户相同(因此当登录成功时重定向到 /dasboard
)
我认为当我使用有效的管理员凭据和 false
(并且视图显示错误的凭据)时,他们自己的身份验证工作正常,如 LoginController.attemptLogin()
returns true
当我使用无效凭据时。
我在 this post 中发现这可能是一个 session 问题,我尝试应用 post 中提到的解决方案。不幸的是,将 protected $primaryKey = 'id';
添加到 SystemUser
class 并没有解决问题。我还将租户 User
class 与 SystemUser
class 进行了比较,但除了我从 SystemUser
等地址中删除的不重要字段外,它们几乎相同。
我不知道如何找出问题发生的位置或如何解决这个问题。目标是将成功登录的管理员重定向到另一个页面 /dashboard
。有人可以帮我找出问题所在吗?当有人可以帮助我获得与租户当前相同的管理员行为时,我已经很高兴了。
提前致谢!
更新 1 @David Barker
关于 session,我认为了解这一点也很重要:
- I use a Vue front end, i give a
不记名令牌to Vue via the
app.js``
我的 session 配置:
<?php
use Illuminate\Support\Str;
return [
'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION', null),
'table' => 'sessions',
'store' => env('SESSION_STORE', null),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN', null),
'secure' => env('SESSION_SECURE_COOKIE', false),
'http_only' => true,
'same_site' => null,
];
我在LoginController->attemptLogin();
函数中做了一个dd($request->session();)
,结果如下。除了 id
和 _token
之外,两个用户的结果相同。 (在这两种情况下,我都在尝试登录之前清除了 cookie)
Illuminate\Session\Store {#490 ▼
#id: "7WI7JUWPnS4pg3EHvaxk5TOKaM9l9UXJi1zJNKuG"
#name: "festipay_session"
#attributes: array:1 [▼
"_token" => "mtMWanYGMUxFHivOqAaEmVQnHDE0hvwKkHMgCswg"
]
#handler: Illuminate\Session\FileSessionHandler {#489 ▼
#files: Illuminate\Filesystem\Filesystem {#198}
#path: "/var/www/domain.com/storage/framework/sessions"
#minutes: "120"
}
#started: true
}
也许这也是一个有趣的信息。左边是管理员的响应(在我单击 login
按钮后),右边是工作租户登录。
我终于找到问题了。这很容易解决。我没有为 Route::group
指定 auth guard
。
原来是这样的:
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () { return redirect('/dashboard'); });
Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard');
Route::get('/logout', 'Auth\LoginController@logout')->name
我把它改成了这样让它工作:
Route::group(['middleware' => 'auth:system_user_web,web'], function () {
Route::get('/', function () { return redirect('/dashboard'); });
Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard');
Route::get('/logout', 'Auth\LoginController@logout')->name