使用OAuthServerBundle测试Symfony 2.8 API

使用OAuthServerBundle测试Symfony 2.8 API,symfony,oauth,phpunit,Symfony,Oauth,Phpunit,我有一个API端点,已经过如下测试: /** @test */ public function an_user_can_get_all_students() { $client = static::createClient(); $crawler = $client->request('GET', '/api/students'); $data = json_decode($client->getResponse()->getContent(), tr

我有一个API端点,已经过如下测试:

/** @test */
public function an_user_can_get_all_students()
{
    $client = static::createClient();

    $crawler = $client->request('GET', '/api/students');
    $data = json_decode($client->getResponse()->getContent(), true);

    $this->assertStatusCode(200, $client);
    $this->assertCount(5, $data);
}
到目前为止,我的测试是绿色的。但是我添加了
OAuthServerBundle
来保护uri
/api/students
。验证我的测试的最佳方法是什么

security.yml

# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        oauth_token:
            pattern: ^/oauth/v2/token
            security: false

        api:
            pattern: ^/api
            fos_oauth: true
            stateless: true
            anonymous: false

    access_control:
        - { path: ^/api, roles: [ IS_AUTHENTICATED_FULLY ] }
简短回答 您应该在授权
中发送访问令牌,在令牌前加上单词“Bearer”:

Authorization: Bearer N2FmNzhhNGM2MTI5N2JhMWJlYj...
为什么你的解决方案有效 链接中的代码:有效,因为静态方法
createClient
使用的内核与10行中的相同:

self::$kernel->getContainer()->get('security.token_storage')->setToken($token);
您可以通过读取以下代码来检查它:。接下来,如果您看到代码为(第50行,第58行),那么您将看到,该授权来源于容器

因此:

1) 您在测试函数的主体和客户机处理的请求之间共享同一个容器。文档中描述了这种剪切:您可以通过客户端方法
绝缘
来防止这种剪切

2) 您可以直接设置
security.token\u存储

3) 然后使用正确的
安全性处理您的请求。令牌存储
并成功授权。(授权控制器具有正确的令牌)

可能第5行、第12-14行是不必要的,因为API不应该使用会话

它在真实生活中应该如何工作 在实际使用的情况下,您的API客户端将通过标题发送带有名称
授权
和值
承载令牌
的令牌。所以,为了测试客户端请求是否有效,您不应该手动设置
security.token\u storage
,而是允许OAuthServerBundle从请求中设置它。这是在第78行中完成的

您可以在以下位置找到有关在客户端中设置标题的文档:

就你而言:

$client->request(
    'GET',
    '/api/students',
    array(),
    array(),
    array(
        'CONTENT_TYPE'          => 'application/json',
        'HTTP_Authorization'    => 'Bearer '.$token_as_string
    )
);
你可以用

$client->insulate();

要在一个测试函数中测试多个访问级别,请显示OAuth服务器包和security.yml的配置,我明白了,您想看到401未经授权的错误?我得到401,但我想得到200。因此,您应该在请求中发送令牌。1) 您知道如何从OAuthBundle获取令牌吗?2) 你知道如何在请求中使用此令牌吗?我已决定使用此令牌:,你能看一下吗?出于好奇,如果你评论5行和12-14行,它仍然有效吗?回答得很好!是的,第五行;12-14是不必要的。回到您的答案,我如何获得您在答案第8行中提到的
$token\u as\u string
?对不起,我对Symfony完全不熟悉。使用
new UsernamePasswordToken
?如果您的
UsernamePasswordToken
实现了TokenInterface(),那么您可以通过getToken()方法获得token的文本表示。太好了!非常感谢。