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

时间:2017-07-11 16:28:36

标签: angular authentication postman middleware 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端点,比如说Dashboard信息。

$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);
}

});

知道我错过了什么?

BTW为了使预检CORS OPTIONS工作,我在应用程序的末尾附加了以下代码,我不确定它是否与问题有关。

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

当然这会渲染 - >选项和 - >匹配过时,这仍然很时髦。可能我所做的只是一种解决方法而不是解决方案。