【问题标题】:How to set database dynamically based on client request in Laravel如何在 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 时等等等等。
  • 请使用租赁套餐。哪个会为您做到这一点

标签: php reactjs laravel rest axios


【解决方案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'));

您应该真正知道自己在做什么,因为它可能存在很大的安全漏洞。

【讨论】:

    猜你喜欢
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 2021-08-10
    • 2012-03-18
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多