如何在 Laravel 中根据客户端请求动态设置数据库
Posted
技术标签:
【中文标题】如何在 Laravel 中根据客户端请求动态设置数据库【英文标题】:How to set database dynamically based on client request in Laravel 【发布时间】:2022-01-17 03:15:55 【问题描述】:我使用 Laravel 应用程序作为后端,并希望通过 axios 请求动态设置数据库连接(并保持它直到页面刷新),该请求将包含要使用的数据库和凭据。
为此,我将接收到的数据库配置存储在会话中,并在我尝试使用的任何控制器的构造函数中设置环境变量。
以下是 .env 中的默认数据库设置:
DB_DATABASE=database1
DB_USERNAME=username1
DB_PASSWORD=password1
但是,问题似乎是会话没有保持活动状态,因为每个发送的请求都包含不同的会话 ID,因此每当我尝试与数据库交互时都会返回访问被拒绝错误,因为会话变量未定义。
以下是客户端发送请求的方式:
axios
.post("https://data-test.io/api/Setconnection",
database: "database2",
username: "username2",
password: "password2",
)
.then((result) =>
// console.log(result);
// do stuff here
);
这就是我在会话中存储数据库连接的方式:
class RootController extends Controller
public function setConnection(Request $request)
session(['database' => $request->database]);
session(['username' => $request->username]);
session(['password' => $request->password]);
return $request->session()->all(); // this returns the correct values
我在 api.php 中设置了这样的路由:
Route::post('/Setconnection',[RootController::class, 'setConnection']);
然后,在所有后续请求中,我以这种方式在构造函数中设置连接:
public function __construct()
Artisan::call('config:cache');
Config::set('database', session('database'));
Config::set('username', session('username'));
Config::set('password', session('password'));
public function getConfig()
return [session('database'),session('username'),session('password')];
// this returns an array of undefined elements.
我在这里犯了一个错误,或者这不是我应该如何动态设置数据库连接?如果没有,那么最好的方法是什么?
【问题讨论】:
当你使用 Laravel 作为后端时,它基本上是一个 API,API 应该是“无状态的”;每次访问时都很新鲜。您的setConnection
逻辑需要针对每个请求运行,例如通过中间件。这基本上就是“登录”到 API 的工作原理;登录,获取令牌,将该令牌与 每个 后续请求一起发送以验证登录/身份。您可以为此使用相同的逻辑,但您需要重新考虑您的方法。
@TimLewis 在这种情况下,鉴于我不想在身份验证过程中使用数据库,哪种方法可以完成这项工作?阅读 Laravel Docs 我看到 Laravel Sanctum 需要建立一个数据库。所以也许发行 JWT 令牌可以在不需要数据库的情况下完成?
如果您不想使用数据库,这在技术上是可以的,但是您需要一些方法来确定要使用的数据库。如果您有一组预定义的连接,那么您可以简单地使用connection: 1
(或其他东西)向您的axois
请求添加一个全局标题,并验证在每个请求上调用setConnection
时等等等等。
请使用租赁套餐。哪个会为您做到这一点
tenancy.dev
【参考方案1】:
正如蒂姆刘易斯所说,API 应该是“无状态”的,没有以前存储的数据可以在每个事务/请求中使用。如果您不想使用数据库来存储动态数据库凭据,则需要在客户端保存动态数据库凭据并在每个请求中发送它们。
但如果你真的想创建可以在 API 中使用会话的“有状态”,你可以关注these instructions。
然后要更改数据库配置,您应该使用Config::set('database.connections.dbdrivername.configname','configvalue')
,不需要Artisan::call('config:cache')
一个例子:
Config::set('database.connections.mysql.database', session('database'));
Config::set('database.connections.mysql.username', session('username'));
Config::set('database.connections.mysql.password', session('password'));
您应该真正知道自己在做什么,因为它可能存在很大的安全漏洞。
【讨论】:
以上是关于如何在 Laravel 中根据客户端请求动态设置数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Framework 4.2/Boot 1.3 中根据 Origin HTTP 请求标头设置动态 Access-Control-Allow-Origin?