Laravel 护照 : How can I properly setup a feature test?

标签 laravel laravel-passport

我正在尝试创建一个功能测试来测试获取 OAuth 访问 token 。使用 Postman 时,一切都运行良好(实际代码),因此我确信在我的测试代码中我没有正确实现设置。

过去,我运行 artisan 命令,然后将 client_secret 复制/粘贴到我的 .env 文件中。因为我使用的是 CI/CD,所以我不能这样做。我需要:

  • 创建一个 artisan 命令来附加 .env
  • oauth_clients 表中读取 secret (似乎是最简单的途径)

我关注了this SO thread帮助到达我所在的位置,但无法使其发挥作用。

这是我的测试:

MyFeatureTest.php

use RefreshDatabase, WithFaker, DatabaseMigrations;

public function setUp(): void
{
    parent::setUp();

    $this->artisan('passport:install');
}


public function a_user_can_get_a_token()
{
    $credentials = [
        'username' => 'username',
        'password' => 'password',
    ];

    $http = $this->postJson('api/v1/login', $credentials);

    $response = json_decode($http->getContent());

    // dd($response);

    $http->assertStatus(200)
        ->assertJsonStructure([
                'token_type', 'expires_in', 'access_token', 'refresh_token',
            ])
            ->assertJson([
                'token_type' => $response->token_type,
                'expires_in' => $response->expires_in,
                'access_token' => $response->access_token,
                'refresh_token' => $response->refresh_token,
            ]);

在我处理登录路由的 Controller 中:

public function __construct()
{
    $this->client = DB::table('oauth_clients')
        ->where('id', 2)
        ->first();
}


...


public function getOauthAccessToken($credentials)
{
    $response = Http::asForm()->post(env('APP_URL') . '/oauth/token', [
        'grant_type' => 'password',
        'client_id' => $this->client->id,
        'client_secret' => $this->client->secret,
        'username' => $credentials['username'],
        'password' => $credentials['password'],
        'scope' => '*',
    ]);

    if ($response->successful()) {
        return $response->json();
    } else {
        dd($response->body());
    }
}

当使用 postman 测试我的路线/ Controller 时,一切都很好。我按预期得到了 Barer 代币。

当我运行功能测试时,我的 Controller 返回 null。 为了排除故障,我尝试了上面的 dd($response->body()) 。这是我得到的:

"{"error":"invalid_client","error_description":"Client authentication failed","message":"Client authentication failed"}"

如果我dd($this->client->secret),我就能看到 key 。这非常令人困惑,因为看起来一切正常......

如何正确设置我的测试,以便在我进行登录测试时护照已准备好/配置?感谢您的任何建议!

最佳答案

谢谢大家的建议!

这就是最终对我有用的东西。由于我是 api 的唯一使用者,因此我不需要返回整个 /oauth/token 响应(尽管它将来可能会有所帮助)。

MyTest.php

 use RefreshDatabase, WithFaker, DatabaseMigrations;

public function setUp(): void
{
    parent::setUp();

    $this->artisan('passport:install', ['--no-interaction' => true,]);
}


/** @test */
public function a_user_can_authenticate_using_email()
{
    $credentials = [
        'username' => '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="512534222511343c30383d7f323e3c" rel="noreferrer noopener nofollow">[email protected]</a>',
        'password' => 'password',
    ];

    $http = $this->postJson('api/v1/login', $credentials)
            ->assertStatus(200);
}

MyController.php

// authenticate the $credentials to get a $user object.

...

return $this->getOauthAccessToken($user);

...

private function getOauthAccessToken($user)
{
    $token = $user->createToken('My Personal Access Token')->accessToken;

    return response()->json($token);
}

我只是验证我是否收到了 200 响应,而不是验证返回的确切 json(这是理想的)。因为我的身份验证有点麻烦(检查多个数据库),所以确保我通过 200 完成所有操作非常重要。

希望这对某人有帮助!

关于Laravel 护照 : How can I properly setup a feature test?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62663597/

相关文章:

Laravel Passport - 连接不良时刷新 token 问题

facebook - Laravel Passport 和 Ionic2 Facebook 登录

Laravel 广播 - 组合多个中间件(网络,身份验证 :api)

php - whereBetween 和 orWhere 获取日期范围内的数据

php - 忽略重音字符 Eloquent 查询

php - Laravel 'User' 模型没有 id 列

带有自定义登录 Controller 的 Laravel 护照

php - Laravel Eloquent 查询 - 无法转换为 int

Laravel:为什么缓存数据是二进制的?

php - Laravel Passport token 生命周期