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

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

ただいまの
回答率

89.12%

【Laravel】POSTする時に送信元と送信先のURLが違っているとGETで送信されてしまう原因は何がかんがえられますか?

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 886

hasshy

score 83

以前、ご相談した内容に関連するのですが、また発生しましたのでご相談させてください。 

【Laravel】FormでPostしてもPostとして送信できない

Laravelの認証にデフォルトで実装されている、パスワードを忘れた場合に再設定するためにメールアドレスを入力するフォームについてです。  
メールアドレスをフォームに入れて送信したところ、500エラーになりました。   

実装当初は動作している事を確認できており、処理自体は変更していないので実装中に何か誤って設定してしまったのかもしれません。
私自身もソースを戻しながら確認をしておりますが、まだエラー原因には至っておりません。

同じような原因を経験された事がある方がいらっしゃればご教示いただけますでしょうか?
もし、情報が足りない場合はご教示ください。

ソース

ルート

認証処理の部分だけ抽出しました。

ルートの構成はmake:authで作られるルート構成のままで使用しておりますが、
マルチログインのサイトですので、コントローラー階層は変えています。

// 管理画面
Route::group([
    'prefix' => 'admin',
], function(){

    // 未ログイン
    Route::group([
        'middleware' => 'guest:admin',
    ], function(){

        // ログイン処理
        Route::get('login', 'Admin\Auth\LoginController@showLoginForm')
            ->name('admin.login');
        Route::post('login', 'Admin\Auth\LoginController@login');

        // パスワードリセット
        Route::get('password/reset', 'Admin\Auth\ForgotPasswordController@showLinkRequestForm')
            ->name('admin.password.request');
        Route::post('password/email', 'Admin\Auth\ForgotPasswordController@sendResetLinkEmail')
            ->name('admin.password.email');
        Route::get('password/reset/{token}', 'Admin\Auth\ResetPasswordController@showResetForm')
            ->name('admin.password.reset');
        Route::post('password/reset', 'Admin\Auth\ResetPasswordController@reset')
            ->name('admin.password.update');

    });
});    

フォームページのルート

メールアドレスを入力して、POSTするページのルートです。  

Route::get('password/reset', 'Admin\Auth\ForgotPasswordController@showLinkRequestForm')
    ->name('admin.password.request');

処理ページのルート

上記フォームからPOSTを受け取って処理するページのルートです。  

Route::post('password/email', 'Admin\Auth\ForgotPasswordController@sendResetLinkEmail')
    ->name('admin.password.email');

フォームのblade

ルート名admin.password.request に該当するページで、
メールを入力するフォームのページです。  

Formの送信先は、ルート名admin.password.emailです。
FormのメソッドもPOSTです。

<!DOCTYPE html>
<html lang="jp">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content=""><meta name="csrf-token" content="hPctaZmgzFB02wNfJjtD1eDICeiKSAyqAz1JIcqe"/>
    <title>タイトル </title>
    <link href="http://localhost:8080/css/app.css" rel="stylesheet">
    <link href="http://localhost:8080/css/admin_style.css" rel="stylesheet">  </head>
  <body class="hold-transition login-page login">
    <p class="card-body">
      パスワードをお忘れですか? <br>
      下記にメールアドレスを入力してパスワードをリセットすると、リセットするためのリンクが送信されます。
    </p>
    <form class="user" method="POST" action="http://localhost:8080/admin/password/email"><input type="hidden" name="_token" value="hPctaZmgzFB02wNfJjtD1eDICeiKSAyqAz1JIcqe">
    <div class="form-group">
        <input class="form-control form-control-user " id="exampleInputEmail" name="email" type="email" aria-describedby="emailHelp" placeholder="メールアドレスを入力してください。"/>      </div>
      <div class="row">
        <div class="col-12">
          <button class="btn btn-primary btn-block btn-flat" type="submit">パスワード初期化リンクを送信</button>
        </div>
      </div>
    </form>
    <hr/>
    <div class="text-center"><a class="small" href="http://localhost:8080/admin/login">ログインページ</a></div>
  </div>
</div>    </div>
</body>
</html>

Exceptions/Handler.php

問題が発生した時に起因した箇所は下記でした。
エラーページを共通化しようとした時に修正したときのものでした。

(プロジェクトディレクトリ)/app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

class Handler extends ExceptionHandler
{
    private $routeBase;

    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        // ルート確認
        $route = app('router')
            ->getRoutes()
            ->match(app('request')
                ->create($request->getRequestUri()))
            ->getName();
        $route = explode('.', $route);
        $this->routeBase = count($route) > 0
            ? $route[0]
            : null;
        return parent::render($request, $exception);
    }

    protected function renderHttpException(HttpExceptionInterface $e) {
        $statusCode = $e->getStatusCode();
        $message = $e->getMessage();

        $redirectURL = $this->routeBase
            ? route(\Config("route.auth_home.{$this->routeBase}"))
            : null;

        return response()->view('errors.common',
            compact('statusCode', 'message', 'redirectURL'),
            $statusCode
        );
    }


}

エラーログの内容

laravelのlog上は下記のエラーが確認できました。  
上記のフォームで送信しているのでPOST送信がされているはずなのですが、GETとして扱われてしまいます。  

local.ERROR: Uncaught Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: The GET method is not supported for this route. Supported methods: POST. in /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:256

全文

[2019-08-17 23:32:51] local.ERROR: Uncaught Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: The GET method is not supported for this route. Supported methods: POST. in /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:256
Stack trace:
#0 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(242): Illuminate\Routing\RouteCollection->methodNotAllowed(Array, 'GET')
#1 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(176): Illuminate\Routing\RouteCollection->getRouteForMethods(Object(Illuminate\Http\Request), Array)
#2 /var/www/app/Exceptions/Handler.php(57): Illuminate\Routing\RouteCollection->match(Object(Illuminate\Http\Request))
#3 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(112): App\Exceptions\Handler->render(Object(Illuminate\Http\Request), Object(Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException))
#4 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleE {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 1): Uncaught Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException: The GET method is not supported for this route. Supported methods: POST. in /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:256
Stack trace:
#0 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(242): Illuminate\\Routing\\RouteCollection->methodNotAllowed(Array, 'GET')
#1 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(176): Illuminate\\Routing\\RouteCollection->getRouteForMethods(Object(Illuminate\\Http\\Request), Array)
#2 /var/www/app/Exceptions/Handler.php(57): Illuminate\\Routing\\RouteCollection->match(Object(Illuminate\\Http\\Request))
#3 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(112): App\\Exceptions\\Handler->render(Object(Illuminate\\Http\\Request), Object(Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException))
#4 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleE at /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:256)
[stacktrace]
#0 {main}
"}

原因と思われる場所

Post前のルートが、password/reset、  
Post送信先のURLがpassword/emailで、POST先のURLが変わっているためエラーになっているのではないかと思います。

  • フォームURL:http://localhost:8080/admin/password/reset
  • 処理URL:http://localhost:8080/admin/password/email

根拠となる理由

同じURLを指定してみたところ正常にPOSTされました。 
これで解決はできるのですが、デフォルトの設定で動作しないので、根本的な原因を探っています。

Route::get('password/email', 'Admin\Auth\ForgotPasswordController@showLinkRequestForm')
    ->name('admin.password.request');
Route::post('password/email', 'Admin\Auth\ForgotPasswordController@sendResetLinkEmail')
    ->name('admin.password.email');
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

自己解決しました。  
httpメソッドが、GET以外の場合はPOSTとして処理をしないといけませんでした。

        switch ($request->method()) {
            case "GET":
                $route = app('router')
                    ->getRoutes()
                    ->match(app('request')
                        ->create($request->getRequestUri()))
                    ->getName();
                break;
            case "POST":
            case "DELETE":
            case "PUT":
                $route = app('router')
                    ->getRoutes()
                    ->match(app('request')
                        ->create($request->getRequestUri(), 'POST'))
                    ->getName();
                break;
        }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • Laravelに関する質問
  • 【Laravel】POSTする時に送信元と送信先のURLが違っているとGETで送信されてしまう原因は何がかんがえられますか?