我正在编写一个Laravel REST API,我正在使用基于用户的令牌进行身份验证。我正在使用中间件检查并让请求通过,到目前为止一直很好。
但是在控制器内部,我想访问有关当前用户的详细信息,这会产生另一个我不想承受的数据库调用。我已经访问数据库以验证并检查中间件中的用户,因此我可以将数据从中间件传递到控制器,方法是将其注入请求数据中。灵感来自角度的Http拦截器,它允许这样做,我想在Laravel。
我理解请求对象是不可变的,在Angular中我们通过克隆请求来实现它。但是我不确定如何在Laravel中实现它。基于我的挖掘,我尝试了一个解决方案,它似乎工作正常,有时会破坏,因为它会删除请求主体的所有先前数据。以下是我现在所做的,它有时会删除实际的请求数据。
<?php
namespace App\Http\Middleware;
use App\Exceptions\Apex\ValidationFailed;
use App\Models\AccessTokens;
use App\Models\Users;
use App\Validators\Apex\v1\UuidValidator;
use Closure;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\Lang;
class SessionControl
{
protected $uuidValidator;
public function __construct(UuidValidator $uuidValidator)
{
$this->uuidValidator = $uuidValidator;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
* @throws HttpResponseException: if the token is not valid or expired.
*/
public function handle($request, Closure $next)
{
$unAuth = response(array(
"message" => Lang::get('messages.UNAUTHORIZED-ACCESS')
), 401);
if (!$request->hasHeader('access_token')
|| !$request->hasHeader('user_id')) {
throw new HttpResponseException($unAuth);
}
try {
$token = $request->header('access_token');
$user_id = $request->header('user_id');
$this->uuidValidator->validate(array("uuid" => $user_id));
$access = AccessTokens::where([
'token' => $token,
])->firstOrFail();
$user = $access->user;
if($user->getUUID($user->uuid) !== $user_id) {
throw new HttpResponseException($unAuth);
}
if (!$access->expires_at->isFuture()) {
throw new HttpResponseException(response(
array("message" => Lang::get('messages.SESSION-EXPIRED')), 401)
);
}
//if user is root set him as super admin to hide him in records
if($user->type === 'ROOT') {
$user = Users::where(['type' => 'SUPER-ADMIN', 'status' => 'ACTIVE'])->firstOrFail();
//setting root = true in request data
$request->merge(['isRoot' => true]);
}
//Inject the user's session data, to avoid multiple database calls to find the user
$request->merge(['userSession' => $user]);
return $next($request);
} catch (ModelNotFoundException $e) {
throw new HttpResponseException($unAuth);
} catch (ValidationFailed $e) {
throw new HttpResponseException($unAuth);
}
}
}
谁能告诉我我在尝试的是不可能的任务?我的意思是我不应该在控制器中注入一个值。我想我很想看到一些东西。如何在不弄乱框架内部的情况下以干净的方式实现,或者我不应该这样做?
我正在使用Laravel 5.5,如果这有任何区别。
这是正确的方法吗,还是我让它变得讨厌?