Silex中间件身份验证在邮递员和浏览器中的工作方式不同



我不是一个有经验的后端开发人员,所以这个问题可能不是正确的问题,但问题是真实的!

我正在使用Silex作为Angular 2应用程序的简单后端,我有一个中间件可以检查用户是否提供了JWT令牌。

$app->before(function (Request $request) use ($app)  {
// Checks if the credential header is provided
if (!$token = $request->headers->get('X-BEARER-TOKEN')) {
return new Response('Bad Request', 400);
}
$data = $app['user.validateToken']($token); // This checks if the JWT token is valid
if(!$data || (int) $data['user_role_id'] != 2){
return new Response('Access Denied', 403);
}
});

我有一个 API 端点返回一些东西,比如仪表板信息。

$app->get('/dashboard', function () use ($app) {
$stmnt = $app['db']->executeQuery(
"SELECT Query"
);
$result = $stmnt->fetchAll();
if($result === false) {
return new Response('Not Found', 404);
}else{
$result = array('message' => 'success', 'status' => 200, 'data' => $result);
return $app->json($result, 200);
}
});

这不起作用,我收到"错误请求",因为请求无法获取标头数据。

令人费解的笔记: 答 - 如果我从 Postman 调用 API,上面的代码效果很好,但是当我从浏览器调用 API(在本例中为 Angular 应用程序(时,我收到一个错误请求。

B - 如果我将凭据逻辑从之前的中间件移动到端点(下面的代码(,那么从 Postman 调用和应用程序调用中一切都运行良好。

$app->get('/dashboard', function (Request $request) use ($app) {
// Checks if the credential header is provided
if (!$token = $request->headers->get('X-BEARER-TOKEN')) {
return new Response('Bad Request', 400);
}
$data = $app['user.validateToken']($token);
if(!$data || (int) $data['user_role_id'] != 2){
return new Response('Access Denied', 403);
}
$stmnt = $app['db']->executeQuery(
"SELECT Query"
);
$result = $stmnt->fetchAll();
if($result === false) {
return new Response('Not Found', 404);
}else{
$result = array_map('intval', $result[0]);
$result = array('message' => 'success', 'status' => 200, 'data' => $result);
return $app->json($result, 200);
}
});

知道我错过了什么吗?

顺便说一句,为了使预检 CORS 选项正常工作,我将以下代码附加到应用程序末尾,我不确定它是否与问题有关。

$app->match("{url}", function($url) use ($app){
return "OK";
})->assert('url', '.*')->method("OPTIONS");

好的,我发现了问题,这很愚蠢,IMO,

问题是没有正确考虑应用程序生命周期, $app->before在$app->选项之前运行,因此当浏览器询问OPTIONS标头是否可以接受时,->before生命周期不知道如何处理它。

将以下代码添加到 -> 之前解决了问题:

if ($request->getMethod() == 'OPTIONS') {
return new Response(null, 204);
}

当然,这使得 ->options 和 ->match 过时了,这仍然很时髦。可能我所做的只是一种解决方法,而不是解决方案。

最新更新