質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

2943閲覧

[Laravel] CsrfTokenが正常で無い場合 → "419 Page Expired"のページが出ないようにしたい

kazoogon

総合スコア281

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/06/13 18:42

編集2019/06/14 13:12

環境

Laravel5.8

作成中の機能

「お問い合わせフォーム」
名前や年齢をFormでControllerに送信、メールを送る。

実現したいこと

・二重送信
・Form送信完了後、戻ってリロード
→上記行った場合に自分の作ったviewを表示させるようにしたい
試したこと

「Csrf tokenを検証」

public function form(Request $request) { if($request->session()->token() !== $request->input('_token')) { return view('Errors/hoge'); //自分で作成したviewを表示したい } $this->sendMail(); //private functionでメール送る   $request->session()->regenerateToken();//tokenの作成 return view('complete'); //完了画面に行く }

これだと2重で送信ボタンclickなどすると、自分の作ったエラーviewが表示されず画像の様なLaravelにデフォルトである419のエラーページが表示されてしまいます。
イメージ説明
よろしくお願いいたします。

追記

//form submitするview //このページは確認画面なので、inputなどはありません <form method="POST" action="/submit"> @csrf <table> <tr> <th>名前</th> <td>{{$hoge->name}}</td> </tr> <tr> <th>メールアドレス</th> <td>{{$hoget->email}}</td> </tr> </table> <button name="submit">送信</button> </form>

追記(aro10さんの回答に対しての追記)

1,フォーム表示時に、 セッションにフォーム用のキーでランダムデータを格納し、フォームのhidden入力欄に代入しておく

form内にLaravelの@csrfを挿入してあります。

2,フォーム送信時に送信内容と格納したセッションデータを検証、不一致の場合は専用のエラーページへ

if($request->session()->token() !== $request->input('_token')) { ```の部分でこれをしていると思いますが、Laravel defaultの419のページが出る。という状態です 追記(進捗状況) --- App\Exceptions\Handler.phpを修正し、自分でExceptionのカスタマイズをした(「Handlerを書き換える」というのを今まではlaravel\framework\src\Illuminate\Foundation\Exceptions\Handler.phpの方だと勘違いしていた)

//App\Exceptions\Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof TokenMismatchException) {
abort(401);
}
}

**問題点 ①abortの代わりにreturn response()->view('errors.401');を使用するとview画面が表示されるが、abort(401)だと画面は真っ白 (できるだけabortを使用したい) ② ・送信完了後、戻ってreloadする場合には対応できる ・ダブルクリックされた場合は、メールが送られた後にエラー画面が表示されてしまう (JSでなくPHPの対応方法はあるか?) 追記(ほぼ解決) --- 上記render関数一番下に下記コードを挿入(というか元々あったやつ)すると401のviewが表示された

return parent::render($request, $exception);

・二重送信は「メールが送られた後にエラー画面が表示されてしまう」のままですが、こちらはJSで対処したいと思います

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fumifumi_60

2019/06/14 00:49 編集

質問の再確認ですが、自分で作ったエラーメッセージで 既存の419を入れ替えたいということでよろしいですか? もしくは、二重送信を防止したいというニュアンスでしょうか?
m.ts10806

2019/06/14 01:38

view側のコードもご提示ください。
kazoogon

2019/06/14 06:55

fumifumi_60さん 二重送信を防止したうえで、自分の作ったエラーメッセージを表示したい。ということです
m.ts10806

2019/06/14 07:14

提示していただきたいのはformが書いてある方のviewです…
guest

回答2

0

CSRFは意図しないリクエストを防ぐシステム全体を覆う仕組みなので、
戻るボタンを押して再表示したフォームの二重送信を防ぐという用途ならば個別に用意したものを使う方が良いです。

一例として

  1. フォーム表示時に、 セッションにフォーム用のキーでランダムデータを格納し、フォームのhidden入力欄に代入しておく
  2. フォーム送信時に送信内容と格納したセッションデータを検証、不一致の場合は専用のエラーページへ
  3. フォーム送信完了後にセッションにフォーム用のキーを削除

などが考えられます。

投稿2019/06/14 03:42

aro10

総合スコア4106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazoogon

2019/06/14 07:11

ご回答ありがとうございます、「追記(aro10さんの回答に対しての追記)」を記載致しました。ご確認お願いいたします
aro10

2019/06/14 07:26

これをやってしまうと、CSRF用のトークンが更新されてしまうのでコメントアウトして、 $request->session()->regenerateToken(); sesssion(["form"=>"ランダムな値")のように、普通のセッションデータで使うと良いかと思います。
kazoogon

2019/06/14 12:47

追記(進捗状況)に記載しましたが、Handler.phpを修正してできそうです(私の勘違いがありました汗) まだ問題点ありますので、何か心当たりありましたらご連絡お願い致します。
guest

0

ベストアンサー

https://readouble.com/laravel/5.8/ja/errors.html
これを参考によしなに修正する事
LaravelデフォルトのCSRFエラーの場合はTokenMismatchExceptionが投げられている

投稿2019/06/14 01:25

hentaiman

総合スコア6421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazoogon

2019/06/14 07:29

回答ありがとうございます。 installしたLaravelそのものを変更する必要が有るってことですよね?? 例 Foundation/Exceptions/Handler.php
hentaiman

2019/06/14 07:43

どの範囲をそのものって言ってるのか分からないけど、例外ハンドラーは変更されること前提に考えられてると思うけど 触られたくないところならvendorの中に入ってるでしょ それも嫌ならlaravelのcsrf対策自体を切ってしまって自前でトークン生成と制御をすればいいですよ csrf対策のプログラムの読み込みはkernelのmiddlewareに書いてあるのでコメントアウトすればいいですよ
kazoogon

2019/06/14 12:48

追記(進捗状況)に記載しましたが、Handler.phpを勘違いしていました汗 まだ問題点ありますので、何か心当たりありましたらご連絡お願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問