我正在使用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知道哪个客户的网站发出请求的最佳方法是什么?我需要指向正确的数据库。另外,这种方法会在性能方面引起任何问题吗?
我将使用2分方法来解决此问题,并且我会使用第一种而不使用第二种方法。
第一种将基于您使用请求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,
],
...
]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句