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

问题描述 投票:0回答:1

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

我使用 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);
}
});

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

令人费解的注释: A - 如果我从 Postman 调用 API,上面的代码运行良好,但是当我从浏览器(在本例中是 Angular 应用程序)调用 API 时,我收到错误请求。

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");
php angular authentication middleware silex
1个回答
0
投票

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

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

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

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

当然,这会导致 ->options 和 ->match 过时,这仍然很时髦。也许我所做的只是一种解决方法,而不是解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.