我想制作具有多个数据库的多租户解决方案(每个租户一个数据库)。例如 example.com 的中心域有注册表单和登录表单等内容,例如 example.com/sign-in 每个客户都是由子域标识的新租户,例如 foo.example.com
登录过程(愉快的场景)
我决定使用这个库:https://tenancyforlaravel.com/ 一切正常,我已经创建了租户,中央域也正常工作。我的问题是,如果我想从中央域登录用户,在重定向到他的租户域后,我会收到 403 Unauthenticated。
这是tenant.php的示例代码
Route::middleware([
'web',
InitializeTenancyBySubdomain::class,
PreventAccessFromCentralDomains::class,
])->group(function () {
Route::middleware(['auth'])->group(function () {
Route::get('/dashboard', function () {
return 'Tenant' . tenant('id');
});
});
});
我把
Auth::Routes();
放入web.php
。我正在使用 Laravel 的 UI Auth。
我缺少什么?非常感谢您的帮助。
首先,您需要使用“租户之间同步资源”功能来保持中央数据库和租户数据库之间的用户数据同步: https://tenancyforlaravel.com/docs/v3/synced-resources- Between-tenants/
然后可以通过“模拟”功能完成用户身份验证: https://tenancyforlaravel.com/docs/v3/features/user-impersonation/
您可以在创建新租户时实现这个想法。您将在租户表中数据列的 json 中添加名为 hash 的属性。创建租户时,为每个租户添加随机的唯一哈希值。然后在登录表单中,您可以通过添加一个称为代码的附加输入来使用中央帐户和租户帐户登录。 在控制器中:
$request->validate([
'email' => 'required|string|email|min:10|max:255',
'password' => 'required|string|min:6|max:255',
'remember_me' => 'nullable|boolean',
]);
$credentials = request(['email', 'password']);
if ($request->has('login_code') && $request->login_code){
$tenant = Tenant::whereJsonContains('data->mapper_hash', $request->login_code)->first();
if (!$tenant) {
return $this->sendError(__('Validation Error. R!'));
}
return $tenant->run(function () use($credentials,$tenant) {
if (!Auth::attempt($credentials,true)) {
return $this->sendError(__('Unauthorized'), ['error' => __('Invalid email or password')]);
} else {
$user = Auth::user();
$url = $tenant->impersonationUrl($user->id,'dashboard');
return $this->sendResponse([
'url' => $url
], __('OK User logged in successfully.'));
}
});
}
if (!Auth::attempt($credentials,true)) {
return $this->sendError('Unauthorized.', ['error' => __('Invalid email or password')]);
}