laravel phpunit 测试与 api 令牌认证

Posted

技术标签:

【中文标题】laravel phpunit 测试与 api 令牌认证【英文标题】:laravel phpunit test with api token authentication 【发布时间】:2018-03-27 22:53:19 【问题描述】:

如何在 phpunit 中添加授权标头?我正在测试一个需要 api_token 的 json api。 laravel 文档提供了一个 actuatorAs 方法。但这在我的情况下不起作用,因为 api 令牌与 users 表没有直接关系。

编辑:

public function test_returns_response_with_valid_request()
    
        $response = $this->json('post', '/api/lookup', [
            'email' => 'user@gmail.com'
        ]);
        $response->assertStatus(200);
        $response->assertJsonStructure([
            'info' => [
                'name'
            ]
        ]);
    

【问题讨论】:

【参考方案1】:

根据documentation.

您还可以通过将保护名称作为第二个参数传递给actingAs 方法来指定应该使用哪个保护来验证给定用户:

$this->actingAs($user, 'api');

【讨论】:

【参考方案2】:

您可以使用 withHeader 方法并传入您的令牌,这适用于我的本地(Laravel 6)

public function test_returns_response_with_valid_request()

    // define your $token here
    $response = $this->withHeader('Authorization', 'Bearer ' . $token)
        ->json('post', '/api/lookup', [
            'email' => 'user@gmail.com'
        ]);

    $response->assertStatus(200);
    $response->assertJsonStructure([
        'info' => [
            'name'
        ]
    ]);

或者你可以使用actingAs 来查看docs here with api guard

public function test_returns_response_with_valid_request()

    $user = factory(User::class)->create();
    $response = $this->actingAs($user, 'api')
        ->json('post', '/api/lookup', [
            'email' => 'user@gmail.com'
        ]);

    $response->assertStatus(200);
    $response->assertJsonStructure([
        'info' => [
            'name'
        ]
    ]);

【讨论】:

【参考方案3】:

根据documentation

public function test_returns_response_with_valid_request()

     $user = factory(User::class)->create();

     $response = $this->actingAs($user)
         ->post('/api/lookup',[
             'email' => 'user@gmail.com'
         ]);

     $response->assertStatus(200);
     $response->assertJsonStructure([
             'info' => [
                 'name'
             ]
         ]);

【讨论】:

【参考方案4】:

根据本文档 https://laravel.com/docs/5.8/api-authentication#passing-tokens-in-requests & https://laravel.com/docs/8.x/http-tests

有多种方法可以将 API 令牌传递给您的应用程序。 您可以根据应用程序的需要选择这些方法中的任何一种。

(查询字符串) 您可以将令牌指定为 api_token 查询字符串值
$response = $this->json('POST', '/api/sth?api_token='.$token, $test_data)->assertSussessful();
(请求有效负载)您可以将令牌作为 api_token 包含在请求的表单参数中
     $response = $this->json('GET', '/api/sth', [
            'headers' => [
                'Accept' => 'application/json',
            ],
            'form_params' => [
                'api_token' => $token,
            ],
        ]);
(Bearer token) 请求的 Authorization 标头中的 Bearer token:
    $response = $this->json('GET', '/api/sth', [
                'headers' => [
                    'Authorization' => 'Bearer '. $token,
                    'Accept' => 'application/json'
                ]
            ]);
(Bearer token) 你可以在请求的 Authorization 标头中使用 withHeaders 方法和 Bearer 令牌:
    $response = $this->withHeaders([
            'Authorization' => 'Bearer '. $token,
            'Accept' => 'application/json'
        ])->post('/api/sth', $test_data);

【讨论】:

请解释您的答案,以便下一位用户知道为什么此解决方案对您有效。另外,总结一下您的答案,以防链接将来停止工作。 我想在request中传递一个token,消费者拿到token后可以和api通信。在我的测试代码中,当我使用身份验证令牌调用 get/post/... api 时,出现了问题。如果有人遇到这种无法传递token来请求的问题,请阅读并按照上面的文档进行操作;

以上是关于laravel phpunit 测试与 api 令牌认证的主要内容,如果未能解决你的问题,请参考以下文章

如何使用phpunit在具有动态URI的laravel中测试REST api

Laravel phpunit 测试需要访问 API 服务进行用户验证

如何使用 API 中间件在 Laravel 中测试 PHPUnit 一个经过身份验证的用户?

如何为调用外部 API 的 Laravel Artisan 命令编写 PHPUnit 测试,而无需物理调用该 API?

如何为邮递员 API 请求编写 Laravel PHPUnit 测试

Laravel 5.2 PHPUnit JSON Api 请求正文未设置