【问题标题】:Laravel/angularjs phpunit XSRF how to test?Laravel/angularjs phpunit XSRF 如何测试?
【发布时间】:2014-09-05 07:56:15
【问题描述】:

我已经设置了一个钩子来在 laravel 中实现 XSRF:

查看

@section('content')
<div class="content" data-ui-view></div>
    <script type="text/javascript">
        window.user = <% $data['user'] %>; 
        document.cookie = "XSRF-TOKEN=<% $data['token'] %>";
    </script>
@stop

控制器

$token = csrf_token();
$this->layout->content = View::make('home.content')->with('data', array('token'=> $token, 'user'=> json_encode($userData)));

过滤

Route::filter('xsrf', function()
{
    if((!isset($_COOKIE['XSRF-TOKEN']) || is_null(Request::header('X-XSRF-TOKEN'))) || ($_COOKIE['XSRF-TOKEN'] !== Request::header('X-XSRF-TOKEN'))){
        return Response::make('Not Found', 404);
    }
});

Route::filter('xhr', function()
{
    if(!Request::ajax()){
        return Response::make('Not Found', 404);
    } 

});

路线

Route::group(array('prefix' => 'api/v1', 'before' => 'xhr|xsrf'), function() {

    /* User */
    Route::post('user', array('as' => 'base.user.register', 'uses' => 'App\Controllers\UserController@register'));

 });

xhr 测试

public function testUser404() {

        $crawler = $this->client->request('GET', '/api/v1/user');

        $this->assertResponseStatus(404);
    }

如何测试 base.user.register 的 xsrf 过滤器?

结束

protected function getCookieValue()
{
    $crawler = $this->client->request('GET', '/');
    $text = $crawler->filter('body > div > script')->eq(0)->text();
    $chunks1 = explode("\n", trim($text));
    $chunks2 = explode("=", trim($chunks1[1]));
    return rtrim($chunks2[2], ';"');
}

public function testUser401() {
    $_COOKIE['XSRF-TOKEN'] = $this->getCookieValue();
    $this->client->setServerParameter('HTTP_X-Requested-With', 'XMLHttpRequest');
    $this->client->setServerParameter('HTTP_X-XSRF-TOKEN', $_COOKIE['XSRF-TOKEN']);
    $crawler = $this->client->request('GET', '/api/v1/user');
    $this->assertResponseStatus(401);
}

这很棘手(我很想听听一些更好的:))但它似乎有效

【问题讨论】:

    标签: angularjs laravel-4 phpunit


    【解决方案1】:

    我不认为这是一个特别好的想法(我很想听到一些更好的想法),但这是我在测试中为 XSRF 所做的:

    protected function getToken() {
        $this->client->request('GET', 'http://localhost/admin/login');
    
        preg_match('/<input name="_token" type="hidden" value="([a-zA-Z0-9]+)">/', $this->client->getResponse()->getContent(), $matches);
    
        return $matches[1];
    }
    
    public function testAdminCanLogin() {
      $this->client->request('POST', '/admin/login', [
        'email'    => $this->email,
        'password' => $this->password,
        '_token'   => $this->getToken()
      ]);
    
      // A successful POST redirects you.
      $this->assertFalse($this->client->getResponse()->isOk());
      $this->assertTrue($this->client->getResponse()->isRedirect());
    }
    

    基本上,这里的测试先请求获取有效令牌,然后在 POST 中将其传递回。

    【讨论】:

    • 谢谢,这可能是一个想法,但我还需要设置一个 cookie 以使 angularjs 工作看看跨站点请求伪造(XSRF)保护docs.angularjs.org/api/ng/service/$http
    • DanSingerman 我已经更新了我的问题,它似乎有效,你怎么看?
    • @Whisher - 我认为您不应该只在 cookie 中设置令牌。它需要在您试图保护请求的表单/页面中。见stackoverflow.com/questions/4463422/…
    • DanSingerman 我正在使用 angularjs,保护的方法是设置一个 cookie,而不是检查 http 标头在这种情况下我不介意 laravel csrf
    • 啊,好吧,有道理。
    猜你喜欢
    • 2017-11-29
    • 2015-11-10
    • 1970-01-01
    • 2019-06-06
    • 2018-10-23
    • 2014-04-30
    • 2017-10-19
    • 2020-12-09
    • 2016-06-04
    相关资源
    最近更新 更多