0

My project is using a modified implementation of Laravel Passport for authentication.

I have a route, /auth/login, which I use for authentication. POST is for logging in, PUT is for refreshing tokens, and DELETE is for logging out. Here's the update method of my controller, which is mapped to PUT /auth/login. It is supposed to find the refresh token in the cookie and use it in the performProxyRequest method. However, when I add the cookie to a request in one of my feature tests, $token is always null.

/**
 * Refresh an access token.
 *
 * @param Request $request
 * @return Response
 * @throws JsonException
 */
public function update(Request $request): Response
{
    $token = Cookie::get(Passport::cookie());

    if (is_null($token)) {
        return response([
            'message' => 'Refresh token not found.',
        ], SymfonyResponse::HTTP_UNAUTHORIZED);
    }

    $request->request->add([
        'refresh_token' => $token
    ]);

    return $this->performProxyRequest($request, 'refresh_token');
}

Here is my current feature test with the different attempts I've tried to add the cookie in.

#[Test]
public function an_update_request_is_successful(): void
{
    // Login first, the cookie will be in the response.
    /** @var Cookie $cookie */
    $cookie = $this->postJson(route('auth.login'), $this->credentials)
        ->getCookie(Passport::cookie());
    
    // Attempt 1: standard approach, using `withCookie`.
    $response = $this->withCookie($cookie->getName(), $cookie->getValue())
        ->putJson(route('auth.refresh-tokens'));
    
    // Attempt 2: same as the first attempt, but without the `route` helper.
    //$response = $this->withCookie($cookie->getName(), $cookie->getValue())
    //    ->putJson('/auth/login');
    
    // Attempt 3: standard approach, using `withUnencryptedCookie`.
    //$response = $this->withUnencryptedCookie($cookie->getName(), $cookie->getValue())
    //    ->putJson(route('auth.refresh-tokens'));
    
    // Attempt 4: a more manual approach using `call`
    //$response = $this->call(
    //    method: 'PUT',
    //    uri: route('auth.login'),
    //    cookies: [
    //        $cookie->getName() => $cookie->getValue(),
    //    ],
    //);
    
    // Attempt 5: manually create a request and dispatch it.
    //$request = Request::create(
    //    uri: route('auth.login'),
    //    method: 'PUT',
    //    cookies: [
    //        $cookie->getName() => $cookie->getValue(),
    //    ],
    //);
    //$response = Route::dispatch($request);

    $response->assertOk()
        ->assertJson(static function (AssertableJson $json): void {
            $json->where('token_type', 'Bearer')
                ->where('expires_in', 900)
                ->has('access_token')
                ->has('refresh_token');
        });
    /** @var Cookie $cookie */
    $cookie = $response->getCookie(Passport::cookie());
    $this->assertSame($response->json('refresh_token'), $cookie->getValue());
    $this->assertTrue($cookie->isHttpOnly());
    $this->assertTrue($cookie->isSecure());
}

No matter what I try, the $token is always null when I run my feature test. I've tried putting break points to insepct the request, dding it, and a few other things. But there cookie is always missing from the request.

I've check the middleware for the request, it's only throttle:login and auth:api, so I don't think there's anything weird going on there.

I've tested this flow using plain cURL requests, the PhpStorm HTTP client, and in my local dev with my frontend application. In all of those cases, using the cookie works. It just doesn't when I'm writing the feature test.

So, I'm not sure what else I can do to get this feature test working.

My Laravel version is 11.0, Passport is 12.0.

3
  • I never heard of Cookie class, this is why it is important to stick to documentation and do what they recommend or show in there, as they always use $request->cookie, never Cookie::. I used Laravel for 8+ years and never used Cookie:: and didn't know it existed at all... I could not find any Cookie:: in their docs Commented Aug 10 at 11:09
  • Hi @matiaslauriti, Thanks for your comment. However, I think that it would do you well to expand your knoweledge of the Laravel framework before giving advice. Please direct your attention to the API documentation - Illuminate\Support\Facades\Cookie::get() - "Retrieve a cookie from the request." Commented Aug 10 at 22:10
  • That is an API documentation, barely used, check the main docs, not the API documentation as there are a lot of "experimental" and "not recommended" features or classes that you should not be using... being there does not mean you should use it, it could be internals of the framework... follow the main docs Commented Aug 11 at 2:45

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.