Silex - 拒绝从服务器端访问客户端

时间:2015-09-17 18:52:58

标签: php symfony silex

在服务器端,我收到一个请求,其中包含客户端想要使用标头中的令牌访问的Uri路径。我的服务器会查看hostnametoken,并确保它们有效。如果他们不是,我想阻止客户端访问API端点。

这是函数

$app->before(function(Request $request) use ($app) {
    $host = $request->getHost();
    $token = $request->headers->get('token');

    if(!$app['isValidTokenService']($token)) {
        $app['monolog']->addInfo(sprintf("%s is a invalid token", $token));
        return $app->abort(401,'Unauthorized - bad credentials');
        //return new Response('Unauthorized - invalid ****',401);
    }

    if(!$app['isValidHostService']($host)) {
        $app['monolog']->addInfo(sprintf("%s is a invalid host", $host));
        return $app->abort(401,'Unauthorized - invalid host');
        //return new Response('Unauthorized - invalid ****',401);
    }

    return 'test';
});

我尝试了return new Response('Unauthorized - invalid ****',401);,允许用户仍然访问终点。 $ app-> abort()似乎像魅力一样工作,但它没有响应客户端我认为它不是处理这种情况的正确方法。

如何正确处理此情况以拒绝访问API端点并向客户端返回正确的错误代码。

1 个答案:

答案 0 :(得分:2)

对不起约书亚,我无法重现你的问题:

$ mkdir silex-test
$ cd silex-test
$ composer require silex/silex phpunit/phpunit
$ mkdir tests

现在在tests文件夹 appTest.php 中创建一个文件:

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Silex\Application;

class appTest extends \PHPUnit_Framework_TestCase
{
    public function testBeforeFilterPriorToRouteMatching()
    {
        $app = new Application();

        $app->before(function () {
            return new Response('before');
        });

        $app->get('/', function() { return new Response('you should never see me!'); });

        $request = Request::create('/');
        $this->assertEquals('before', $app->handle($request)->getContent(), "before test didn't canceled the execution!");

    }
}

现在只需执行测试:

$ vendor/bin/phpunit tests/appTest.php
PHPUnit 4.8.7 by Sebastian Bergmann and contributors.

.

Time: 201 ms, Memory: 6.00Mb

OK (1 test, 1 assertion)

正如您所看到的那样,/ route的控制器从未被调用过,因此Silex正在按预期工作。

这只会给我带来一个问题:你使用的是哪个版本? (我已经尝试使用1.3和dev-master这是2.0@dev)This PR(虽然有点过时)解决了之前中间件。

更新

在上面的代码中,我试图证明return new Response('before')确实取消了所有其他执行。如果你看看断言:

$this->assertEquals('before', $app->handle($request)->getContent(), "before test didn't canceled the execution!");

我将处理一个请求的结果与应该返回字符串you should never see me!的/ URI进行比较,但它返回字符串before,因为before过滤器返回带有字符串{的响应永远不会调用{1}}和路径路径的控制器代码。

如果要仔细检查,请将控制器代码更改为:

before

并检查运行测试($app->get('/', function() { echo "You'll never see me as this is not called because of the before filter"; return new Response('you should never see me!'); }); )是否永远不会输出字符串您将永远不会看到我,因为之前的过滤器没有调用它,因为从不调用控制器代码