Laravel中密码确认后如何提交原POST请求至目标方法?
解决Laravel密码确认后无法POST提交表单的问题
问题核心:默认的password.confirm中间件验证通过后会以GET请求重定向回原页面,导致原POST请求的数据丢失,无法触发目标方法。
解决方案步骤:
自定义密码确认控制器,重写验证逻辑
创建一个继承默认认证控制器的自定义控制器,修改验证成功后的处理逻辑,让它带着原POST数据转发请求:namespace App\Http\Controllers\Auth; use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; use App\Http\Controllers\Controller; class CustomPasswordConfirmController extends Controller { public function confirmPassword(Request $request) { $request->validate([ 'password' => ['required', 'current_password'], ]); $request->session()->put('auth.password_confirmed_at', time()); // 读取之前存储的POST请求信息 if ($prevRequest = Session::get('pending_post_request')) { Session::forget('pending_post_request'); // 以POST方式重定向并携带原表单数据 return redirect()->to($prevRequest['url']) ->withInput($prevRequest['data']) ->method($prevRequest['method']); } return redirect()->intended('/'); } public function showConfirmForm() { return view('auth.confirm-password'); } }替换默认的密码确认路由
在routes/web.php中,将默认的password.confirm路由指向自定义控制器:Route::get('/password/confirm', [\App\Http\Controllers\Auth\CustomPasswordConfirmController::class, 'showConfirmForm']) ->middleware('auth') ->name('password.confirm'); Route::post('/password/confirm', [\App\Http\Controllers\Auth\CustomPasswordConfirmController::class, 'confirmPassword']) ->middleware('auth');创建中间件存储原POST请求信息
生成一个中间件,用于在触发密码确认前,把当前POST请求的URL、方法和数据存入Session:php artisan make:middleware StorePendingPostRequest编辑中间件文件
app/Http/Middleware/StorePendingPostRequest.php:namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; class StorePendingPostRequest { public function handle(Request $request, Closure $next) { // 仅对未确认密码的POST请求存储数据 if ($request->isMethod('POST') && !Auth::user()->passwordConfirmedRecently()) { Session::put('pending_post_request', [ 'url' => $request->fullUrl(), 'method' => $request->method(), 'data' => $request->all(), ]); } return $next($request); } }更新目标路由的中间件配置
在fetchResult路由中,添加自定义的存储中间件,确保在password.confirm前执行:Route::post('fetchResult', [ReportController::class, 'fetchResult']) ->name('fetchComplaintResult') ->middleware([ 'auth', \App\Http\Middleware\StorePendingPostRequest::class, 'password.confirm:password.confirm,1' ]);
原理说明:
- 当用户提交POST表单时,
StorePendingPostRequest中间件先把请求的URL、方法和数据存入Session。 password.confirm中间件检测到用户未确认密码,跳转至密码确认页面。- 用户输入密码验证通过后,自定义控制器读取Session中存储的请求信息,以POST方式重定向回目标URL并携带原表单数据,最终触发
fetchResult方法。
内容的提问来源于stack exchange,提问作者Md. Shamvil Hossain
相关产品推荐
相关产品推荐

