Markdown

測試環境不會驗證 CSRF token 的問題

測試環境不會驗證 CSRF token,總是會通過

可以在 VerifyCsrfToken Middleware 中看到 $this->runningUnitTests()
@Illuminate\Foundation\Http\Middleware\VerifyCsrfToken

/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed * * @throws \Illuminate\Session\TokenMismatchException */ public function handle($request, Closure $next) { if ( $this->isReading($request) || $this->runningUnitTests() || $this->inExceptArray($request) || $this->tokensMatch($request) ) { return tap($next($request), function ($response) use ($request) { if ($this->shouldAddXsrfTokenCookie()) { $this->addCookieToResponse($request, $response); } }); } throw new TokenMismatchException('CSRF token mismatch.'); }

尚未調整環境前 PASS

public function testCreateArticleSuccess() { //$this->app['env'] = 'production'; $this->repositoryMock ->shouldReceive('create') ->once(); // 初始化 Session ,因為需要避免 CSRF 的 token Session::start(); $parameters = [ 'title' => 'title 999', 'body' => 'body 999', //'_token' => csrf_token(), // 手動加入 _token ]; $response = $this->post('articles', $parameters); $response->assertRedirect('articles'); }
$ ./vendor/bin/phpunit
PHPUnit 8.5.6 by Sebastian Bergmann and contributors.

........                                                            8 / 8 (100%)

Time: 623 ms, Memory: 26.00 MB

OK (8 tests, 23 assertions)

調整環境後沒帶 token 不會通過

public function testCreateArticleSuccess() { $this->app['env'] = 'production'; $this->repositoryMock ->shouldReceive('create') ->once(); // 初始化 Session ,因為需要避免 CSRF 的 token Session::start(); $parameters = [ 'title' => 'title 999', 'body' => 'body 999', //'_token' => csrf_token(), // 手動加入 _token ]; $response = $this->post('articles', $parameters); $response->assertRedirect('articles'); }
1) Tests\Feature\ArticleControllerTest::testCreateArticleSuccess
Response status code [419] is not a redirect status code.
Failed asserting that false is true.

調整環境後帶上 token

public function testCreateArticleSuccess() { $this->app['env'] = 'production'; // 會呼叫到 ArticleRepository::create $this->repositoryMock ->shouldReceive('create') ->once(); // 初始化 Session ,因為需要避免 CSRF 的 token Session::start(); $parameters = [ 'title' => 'title 999', 'body' => 'body 999', '_token' => csrf_token(), // 手動加入 _token ]; $response = $this->post('articles', $parameters); // 完成後會導向列表頁 $response->assertRedirect('articles'); }
$ ./vendor/bin/phpunit
PHPUnit 8.5.6 by Sebastian Bergmann and contributors.

........                                                            8 / 8 (100%)

Time: 623 ms, Memory: 26.00 MB

OK (8 tests, 23 assertions)

Reference:
https://stackoverflow.com/questions/37734620/laravel-phpunit-always-passes-csrf

留言