【问题标题】:Laravel API connecting to multiple databasesLaravel API 连接多个数据库
【发布时间】:2016-03-22 18:55:48
【问题描述】:

我正在使用 Laravel (Lumen) 构建一个 REST API。这个想法是这个 API 为多个食品订购网站提供后端。它们共享相同的后端逻辑(模型、控制器等)。这样每个网站只需要它自己的前端应用程序,我打算为此使用 Angular。每个网站都有自己的数据(产品、页面等),这些数据必须存储在不同的数据库中。

我在config/databases.php 中定义了多个连接用于测试目的。现在我可以在查询对应的数据库之前动态设置连接,像这样:

class ProductController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {   
        $products = new Product;
        $products->setConnection('customer_two'); // <--
        $products = $products->get();

        return response()->json($products);
    }
}

例如,缓存也可以做到这一点。

让 API 知道是哪个客户的网站提出了请求的最佳方式是什么?我需要指向正确的数据库。此外,这种方法是否会导致性能方面的任何问题?

【问题讨论】:

  • 您的 API 有身份验证吗?或者你不需要它?
  • 是的,我将使用 JWT (scotch.io/tutorials/…) 让管理员登录和管理他们的网站。但并非所有路由都需要令牌来检索数据。

标签: api laravel-5 multiple-databases connection lumen


【解决方案1】:

我会使用两管齐下的方法来解决这个问题,我会使用第一个而不是第二个。

第一个将基于您使用请求 api 的路由。例如,您可以使用 /api/{site} 之类的前缀定义路由。这样,您的所有 api 端点都将基于请求的站点变量。例如。 /api/site1/login 将使用数据库site1/api/site2/login 将使用数据库site2

第二部分是使用 JWT 像您上面提到的那样进行身份验证,并在每个请求上使用中间件来检查经过身份验证的用户是否实际上是该特定站点用户的一部分。但是,这仅对经过身份验证的路由非常有用,并且仍然使您的未经身份验证的路由容易被滥用,但是,如果合法用户在您的站点上并且您的站点正在从 api 请求数据,则您应该返回正确的 site 数据无论如何,任何恶意访问都只会获取公共数据。

可能还有第三种选择。使用 JWT,您可以创建自定义声明。这些自定义声明可用于存储正在使用的站点以及要访问的数据库。我自己没有这样做,但一直在考虑做一些类似的事情来根据我的 api 对客户端进行身份验证,以及在此基础上进行基于用户的身份验证。这意味着每个端点都至少要经过客户端身份验证,而其他端点也将经过用户身份验证以及客户端身份验证。

使用中间件在运行时轻松更改数据库连接。

中间件:app/Http/Middleware/DatabaseConnectionChooser.php

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Routing\Route;

class DatabaseConnectionChooser
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        /** @var Route $route */
        $route = app('router')->getRoutes()->match($request);

        $connection = $route->getParameter('connection');

        app('db')->setDefaultConnection($connection);

        return $next($request);
    }
}

将此中间件添加到 app/Http/Kernel.php 类的 $middleware 属性中。

protected $middleware = [
    ...        
    \App\Http\Middleware\DatabaseConnectionChooser::class,
];

创建路由以指定站点,也就是数据库连接。

app/Http/routes.php

app('router')->get('/{connection}/', function () {
    return app('db')->getDefaultConnection();
});

在您的配置中设置您的数据库连接。

config/database.php

'connections' => [
    ...

    'site1' => [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST', 'localhost'),
        'database'  => env('DB_DATABASE', 'forge1'),
        'username'  => env('DB_USERNAME', 'forge1'),
        'password'  => env('DB_PASSWORD', ''),
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
    ],

    'site2' => [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST', 'localhost'),
        'database'  => env('DB_DATABASE', 'forge2'),
        'username'  => env('DB_USERNAME', 'forge2'),
        'password'  => env('DB_PASSWORD', ''),
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
    ],

    ...
]

【讨论】:

  • 感谢您的回答。 但是,如果合法用户在您的网站上并且您的网站正在从 api 请求数据,那么您的未经身份验证的路由仍然会被滥用,您应该返回正确的网站数据,并且任何恶意访问只会获取公共数据无论如何我应该想到什么样的虐待?此外,客户端和用户身份验证之间的区别对我来说并不是很清楚。我确实知道 Angular 会自动发送带有请求的“X-CSRF-TOKEN”,laravel 会检查 POST 请求。
  • 滥用不是来自您自己的网站,而是来自其他来源的外部恶意攻击。由于您有开放的 GET 请求,因此可以从任何地方访问它们,例如用于 DDOS 攻击等。
  • 至于客户端与用户身份验证的区别在于:基于身份验证的用户例如使用用户名/电子邮件和密码来验证用户身份,而基于客户端的身份验证使用某种标识符或证书/令牌进行身份验证应用程序,例如客户端可以是 Angular 应用程序或移动应用程序。这里的诀窍是在不泄露您的密钥/令牌的情况下验证应用程序(客户端)。希望这会有所帮助。
  • 你知道在 Laravel 中动态设置连接(正如我在帖子中展示的那样)有什么缺点吗?因为 Laravel 需要不断地(重新)连接到不同的数据库?
  • 恕我直言,我认为您的方法会出现错误,因为数据库连接是在控制器中设置的,因此如果您在其中一条路线中错过了一个连接,它将无法按预期工作。我的建议是使用一种中间件方法,该方法设置为在每个请求上全局运行 - 这样您甚至可以在点击控制器之前将连接设置为正确的数据库。将代码添加到新答案。
猜你喜欢
  • 1970-01-01
  • 2017-04-11
  • 2021-05-27
  • 2022-07-06
  • 2020-12-19
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
相关资源
最近更新 更多