Laravel未认证用户访问指定页面时保留URL参数问题
当然可以实现这个需求!咱们只需要调整认证中间件的重定向逻辑,同时确保登录成功后能跳回带参数的原页面,具体步骤如下:
1. 自定义带参数传递的认证中间件
框架默认的auth中间件不会携带原请求的查询参数,所以我们需要自定义一个中间件来实现这个功能:
复制默认的
Authenticate中间件(路径:app/Http/Middleware/Authenticate.php),重命名为AuthenticateWithParams.php修改中间件里的
redirectTo方法,把原请求的查询参数拼接到登录页的URL中:<?php namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; class AuthenticateWithParams extends Middleware { /** * Get the path the user should be redirected to when they are not authenticated. * * @param \Illuminate\Http\Request $request * @return string|null */ protected function redirectTo($request) { if (! $request->expectsJson()) { // 获取当前请求的所有查询参数 $queryParams = $request->query(); // 生成带参数的登录页URL(确保login路由已设置name属性) return route('login', $queryParams); } } }在
app/Http/Kernel.php的$routeMiddleware数组中注册这个新中间件:protected $routeMiddleware = [ // ...其他中间件 'auth.with.params' => \App\Http\Middleware\AuthenticateWithParams::class, ];把原来的pay路由组中的
auth中间件替换成新的auth.with.params:Route::group(['middleware'=> ['auth.with.params']], function(){ Route::get('/pay', 'PayController@index')->name('pay'); });
2. 确保登录路由是命名路由
为了让route('login', $params)能正确生成带参数的URL,你的登录路由需要设置name属性:
Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login');
3. 登录成功后跳转回带参数的原页面
默认登录成功后会跳转到首页,我们需要修改LoginController,让它跳回之前的pay页面(带参数):
在app/Http/Controllers/Auth/LoginController.php中添加authenticated方法:
use Illuminate\Http\Request; protected function authenticated(Request $request, $user) { // 获取中间件存在session里的原请求地址 $intendedUrl = session('url.intended'); // 如果原地址是pay页面,直接跳转回去 if ($intendedUrl && str_contains($intendedUrl, '/pay')) { return redirect($intendedUrl); } // 其他情况跳转到默认首页 return redirect()->intended('/home'); }
4. 测试验证
现在当未认证用户访问http://secondsite.com/pay?param1=value¶m2=value时,会自动重定向到http://secondsite.com/login?param1=value¶m2=value,登录成功后会跳转回带参数的pay页面,完美保留原有参数!
另外,你可以根据需求在PayController的index方法中直接通过$request->param1获取这些参数,不需要依赖session(当然如果需要持久化参数也可以存到session里)。
内容的提问来源于stack exchange,提问作者Pablo

