Reputation:
I'm trying to test my API auth methods, so I created ConfirmPasswordControllerTest with:
/** @test */
public function confirm_password_confirms()
{
$user = factory(User::class)->create();
$data = ['password' => 'password'];
$response = $this->actingAs($user)
->post('api/password-confirmation', $data);
dd($response);
$response->assertStatus(200);
}
I use dd() to check error messages in the response and I see all time:
RuntimeException: Session store not set on request.
I can't understand what happens here, I'm using Laravel Sanctum so my api routes have the auth:sanctum middleware.
EDIT: If I don't include any data in the post like:
$response = $this->postJson('api/password-confirmation');
The test runs as expected:
{"message":"The given data was invalid.","errors":{"password":["The password field is required."]}}
EDIT 2: I debug the app and I see the problem is with the PasswordConfirmController:
public function confirm(Request $request)
{
$request->validate($this->rules(), $this->validationErrorMessages());
$this->resetPasswordConfirmationTimeout($request); //HERE
return $request->wantsJson()
? new Response('', 204)
: redirect()->intended($this->redirectPath());
}
It calls resetPasswordConfirmationTimeout() and this method need to use a session:
protected function resetPasswordConfirmationTimeout(Request $request)
{
$request->session()->put('auth.password_confirmed_at', time());
}
Upvotes: 3
Views: 1698
Reputation: 430
This is quite an old question, but I ran into a similar problem and spent some time solving it. It is quite simple, but not obvious.
If EnsureFrontendRequestsAreStateful
middleware is used for Sanctum, then there is interesting logic that connects additional middlewares (frontendMiddleware()
) if the request comes from the frontend.
The frontendMiddleware
method contains StartSession::class
, which we need to start the session. The condition for its triggering is the presence of referer
or origin
headers with domain from sanctum.stateful
config.
Accordingly, all we need to do is add a header to the request.
$response = $this->actingAs($user)
->post(
'api/password-confirmation',
$data,
['referer' => 'localhost'], //set any domain from `sanctum.stateful` config.
);
Upvotes: 0