You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9.x redirect()->intended未跳转至预期URL反而返回原路由问题

Laravel 9密码确认后无法跳转至POST路由的解决方案

问题根源

Laravel 默认的 password.confirm 中间件在拦截非GET请求时,仅会将目标URL存入session的url.intended字段,但丢失了请求方法(如POST)和提交的表单数据。因此密码确认完成后,redirect()->intended()只能跳转到对应的GET路由,无法还原原本的POST请求逻辑。

解决步骤

1. 自定义密码确认中间件

创建一个继承自默认中间件的自定义中间件,用于存储请求方法和表单数据:

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\EnsurePasswordIsConfirmed as BaseMiddleware;

class EnsurePasswordIsConfirmedWithMethod extends BaseMiddleware
{
    protected function storeIntendedUrl($request)
    {
        // 存储完整目标URL、请求方法及表单数据
        $request->session()->put([
            'url.intended' => $request->fullUrl(),
            'request.method' => $request->method(),
            'request.input' => $request->all(),
        ]);
    }
}

2. 替换默认中间件别名

在app/Http/Kernel.php中,将默认的password.confirm中间件替换为自定义的:

protected $routeMiddleware = [
    // 其他中间件...
    'password.confirm' => \App\Http\Middleware\EnsurePasswordIsConfirmedWithMethod::class,
];

3. 修改密码确认路由的处理逻辑

更新POST类型的/confirm-password路由,根据session存储的信息还原原请求:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

Route::post('/confirm-password', function (Request $request) {
    if (!Hash::check($request->password, $request->user()->password)) {
        return back()->withErrors([
            'password' => ['提供的密码与记录不符。']
        ]);
    }

    $request->session()->passwordConfirmed();

    // 从session取出存储的请求信息
    $intendedUrl = $request->session()->pull('url.intended', '/');
    $method = $request->session()->pull('request.method', 'GET');
    $input = $request->session()->pull('request.input', []);

    // GET请求直接跳转
    if ($method === 'GET') {
        return redirect()->to($intendedUrl);
    }

    // 非GET请求生成自动提交的表单,还原请求方法和数据
    return response()->view('auth.password.redirect-form', [
        'url' => $intendedUrl,
        'method' => $method,
        'input' => $input,
    ]);
})->middleware(['auth', 'throttle:6,1']);

4. 创建自动跳转表单视图

在resources/views/auth/password/目录下新建redirect-form.blade.php,用于自动提交表单还原原请求:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>正在跳转...</title>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            document.getElementById('redirect-form').submit();
        });
    </script>
</head>
<body>
    <form id="redirect-form" action="{{ $url }}" method="{{ strtolower($method) }}">
        @foreach($input as $key => $value)
            @if(is_array($value))
                @foreach($value as $subKey => $subValue)
                    <input type="hidden" name="{{ $key }}[{{ $subKey }}]" value="{{ $subValue }}">
                @endforeach
            @else
                <input type="hidden" name="{{ $key }}" value="{{ $value }}">
            @endif
        @endforeach
        <p>如果未自动跳转,请点击下方按钮:</p>
        <button type="submit">继续</button>
    </form>
</body>
</html>

原理说明

通过自定义中间件扩展了原有的意图存储逻辑,不仅保存目标URL,还记录了请求方法和表单数据。密码确认完成后,针对非GET请求,通过生成自动提交的表单来还原原本的请求,从而实现跳转到POST路由并执行对应的保存逻辑。

内容的提问来源于stack exchange,提问作者Ashaurance Heavens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 20:43:12