我会使用两管齐下的方法来解决这个问题,我会使用第一个而不是第二个。
第一个将基于您使用请求 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,
],
...
]