前提・実現したいこと
初学習者です
公式チュートリアル
記事の管理アプリについてですが、記事の新規作成と編集、タグの新規作成と編集の際にエラーが発生しています。
発生している問題・エラーメッセージ
bakeコマンドで作成したコード。Formヘルパーを使用してadd/editを作成しているのに下記のエラーがでる
Missing or invalid CSRF cookie. if (!$this->_verifyToken($cookie)) { $exception = new InvalidCsrfTokenException(__d('cake', 'Missing or invalid CSRF cookie.')); $expiredCookie = $this->_createCookie('', $request)->withExpired(); $exception->responseHeader('Set-Cookie', $expiredCookie->toHeaderValue());
該当のソースコード
src/application.php
<?php declare(strict_types=1); /** * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @link https://cakephp.org CakePHP(tm) Project * @since 3.3.0 * @license https://opensource.org/licenses/mit-license.php MIT License */ namespace App; use Cake\Core\Configure; use Cake\Core\Exception\MissingPluginException; use Cake\Error\Middleware\ErrorHandlerMiddleware; use Cake\Http\BaseApplication; use Cake\Http\Middleware\BodyParserMiddleware; use Cake\Http\Middleware\CsrfProtectionMiddleware; use Cake\Http\MiddlewareQueue; use Cake\Routing\Middleware\AssetMiddleware; use Cake\Routing\Middleware\RoutingMiddleware; // use Cake\Network\Exception\InvalidCsrfTokenException; // use Authentication\AuthenticationService; // use Authentication\AuthenticationServiceInterface; // use Authentication\AuthenticationServiceProviderInterface; // use Authentication\Middleware\AuthenticationMiddleware; // use Psr\Http\Message\ServerRequestInterface; /** * Application setup class. * * This defines the bootstrapping logic and middleware layers you * want to use in your application. */ class Application extends BaseApplication // implements AuthenticationServiceProviderInterface { /** * Load all the application configuration and bootstrap logic. * * @return void */ public function bootstrap(): void { $this->addPlugin('Migrations'); // Call parent to load bootstrap from files. parent::bootstrap(); if (PHP_SAPI === 'cli') { $this->bootstrapCli(); } /* * Only try to load DebugKit in development mode * Debug Kit should not be installed on a production system */ if (Configure::read('debug')) { $this->addPlugin('DebugKit'); } // Load more plugins here } /** * Setup the middleware queue your application will use. * * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup. * @return \Cake\Http\MiddlewareQueue The updated middleware queue. */ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { $middlewareQueue // Catch any exceptions in the lower layers, // and make an error page/response ->add(new ErrorHandlerMiddleware(Configure::read('Error'))) // Handle plugin/theme assets like CakePHP normally does. ->add(new AssetMiddleware([ 'cacheTime' => Configure::read('Asset.cacheTime'), ])) // Add routing middleware. // If you have a large number of routes connected, turning on routes // caching in production could improve performance. For that when // creating the middleware instance specify the cache config name by // using it's second constructor argument: // `new RoutingMiddleware($this, '_cake_routes_')` ->add(new RoutingMiddleware($this)) // Parse various types of encoded request bodies so that they are // available as array through $request->getData() // https://book.cakephp.org/4/en/controllers/middleware.html#body-parser-middleware ->add(new BodyParserMiddleware()) // Cross Site Request Forgery (CSRF) Protection Middleware // https://book.cakephp.org/4/en/controllers/middleware.html#cross-site-request-forgery-csrf-middleware ->add(new CsrfProtectionMiddleware([ 'httponly' => true, ])); return $middlewareQueue; } /** * Bootstrapping for CLI application. * * That is when running commands. * * @return void */ protected function bootstrapCli(): void { try { $this->addPlugin('Bake'); } catch (MissingPluginException $e) { // Do not halt if the plugin is missing } $this->addPlugin('Migrations'); // Load more plugins here } // public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue // { // $middlewareQueue // // ... 前に追加された他のミドルウェア // ->add(new RoutingMiddleware($this)) // // RoutingMiddleware の後に認証を追加 // ->add(new AuthenticationMiddleware($this)); // return $middlewareQueue; // } // public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface // { // $authenticationService = new AuthenticationService([ // 'unauthenticatedRedirect' => '/users/login', // 'queryParam' => 'redirect', // ]); // // identifiers を読み込み、email と password のフィールドを確認します // $authenticationService->loadIdentifier('Authentication.Password', [ // 'fields' => [ // 'username' => 'email', // 'password' => 'password', // ] // ]); // // authenticatorsをロードしたら, 最初にセッションが必要です // $authenticationService->loadAuthenticator('Authentication.Session'); // // 入力した email と password をチェックする為のフォームデータを設定します // $authenticationService->loadAuthenticator('Authentication.Form', [ // 'fields' => [ // 'username' => 'email', // 'password' => 'password', // ], // 'loginUrl' => '/users/login', // ]); // return $authenticationService; // } }
記事作成
php
1<h1>記事の追加</h1> 2<?php 3 echo $this->Form->create($article); 4 echo $this->Form->control('user_id', ['type' => 'hidden', 'value' => 1]); 5 echo $this->Form->control('title'); 6 echo $this->Form->control('body', ['rows'=>'3']); 7 echo $this->Form->control('tags._ids', ['options' => $tags]); 8 echo $this->Form->button(__('Save Article')); 9 echo $this->Form->end(); 10?>
記事編集
<h1>記事の編集</h1> <?php echo $this->Form->create($article); echo $this->Form->control('user_id', ['type'=>'hidden']); echo $this->Form->control('title'); echo $this->Form->control('body', ['row'=>'3']); echo $this->Form->control('tag_string', ['type' => 'text']); echo $this->Form->button(__('Save Article')); echo $this->Form->end(); ?>
タグ作成
<?php /** * @var \App\View\AppView $this * @var \App\Model\Entity\Tag $tag */ ?> <div class="row"> <aside class="column"> <div class="side-nav"> <h4 class="heading"><?= __('Actions') ?></h4> <?= $this->Html->link(__('List Tags'), ['action' => 'index'], ['class' => 'side-nav-item']) ?> </div> </aside> <div class="column-responsive column-80"> <div class="tags form content"> <?= $this->Form->create($tag) ?> <fieldset> <legend><?= __('Add Tag') ?></legend> <?php echo $this->Form->control('title'); echo $this->Form->control('articles._ids', ['options' => $articles]); ?> </fieldset> <?= $this->Form->button(__('Submit')) ?> <?= $this->Form->end() ?> </div> </div> </div>
タグ編集
<?php /** * @var \App\View\AppView $this * @var \App\Model\Entity\Tag $tag */ ?> <div class="row"> <aside class="column"> <div class="side-nav"> <h4 class="heading"><?= __('Actions') ?></h4> <?= $this->Form->postLink( __('Delete'), ['action' => 'delete', $tag->id], ['confirm' => __('Are you sure you want to delete # {0}?', $tag->id), 'class' => 'side-nav-item'] ) ?> <?= $this->Html->link(__('List Tags'), ['action' => 'index'], ['class' => 'side-nav-item']) ?> </div> </aside> <div class="column-responsive column-80"> <div class="tags form content"> <?= $this->Form->create($tag) ?> <fieldset> <legend><?= __('Edit Tag') ?></legend> <?php echo $this->Form->control('title'); echo $this->Form->control('articles._ids', ['options' => $articles]); ?> </fieldset> <?= $this->Form->button(__('Submit')) ?> <?= $this->Form->end() ?> </div> </div> </div>
試したこと
別のteratail質問参照
https://teratail.com/questions/165237
補足情報(FW/ツールのバージョンなど)
cake4, php7.4, xamppVM
フォームを表示したときに、Cookieに csrfToken がセットされていますか? ブラウザの開発者ツールなどで確認してみてください。(DebugKitを入れているならRequestパネルでの確認でも良いです。
src/Application.phpの内容はすべて提示していないように見えます。可能であればすべて提示してください。
いつもありがとうございます!!!
指摘された点追加完了したので確認いただければ幸いです!
もしかして、CsrfProtectionMiddlewareの多重登録をしていませんか?config/routes.phpでも登録しているなら、src/Application.phpでの登録は不要です。
その辺りはいじっていなく確認しましたが、routes.phpに登録してないと思います。
提示してもらった限りでは、CookieのcsrfTokenとPOSTのcsrfTokenは一致しているようなので原因が判りませんね…あとはXDebugでブレークしながらトークンの検証を行っている部分のコードを追っていくしか解決方法を見つけれなさそうです。
nojimageさんいつもありがとうございます。
ちょっと地道にやってみます!!
回答1件
あなたの回答
tips
プレビュー