Laravel 10多语言站点登录重定向至原页面问题求助
解决Laravel多语言站点登录后重定向至原页面的问题
核心思路
要实现登录后回到用户原访问页面,关键是正确传递原页面URI并安全验证重定向目标,同时适配多语言前缀的URI结构。以下是分步解决方案:
1. 传递原页面URI到登录页面
在登录链接或登录表单中,添加隐藏字段携带当前页面的完整URI(包含语言前缀):
<!-- 登录链接示例 --> <a href="{{ route('login') }}?return_uri={{ url()->current() }}">登录</a> <!-- 登录表单中添加隐藏字段 --> <form method="POST" action="{{ route('login') }}"> @csrf <input type="hidden" name="return_uri" value="{{ request()->get('return_uri') ?? url()->previous() }}"> <!-- 其他登录字段 --> </form>
这里优先取URL参数中的return_uri(从其他页面跳转过来时携带),否则用url()->previous()获取上一页地址。
2. 修改LoginController重定向逻辑
重写authenticated方法,优先验证并跳转到原页面,无效时再跳转用户语言首页:
use Illuminate\Http\Request; class LoginController extends Controller { // ... 其他默认方法 protected function authenticated(Request $request, $user) { $returnUri = $request->input('return_uri'); // 验证重定向URI合法性:必须是本站地址,且排除登录/注册等页面 if ($returnUri && $this->isValidRedirect($returnUri)) { return redirect()->to($returnUri); } // 无合法原页面时,跳转到用户所属语言的首页 $userLocale = $user->locale ?? app()->getLocale(); // 假设用户模型有locale字段存储语言偏好 return redirect()->route('home', ['locale' => $userLocale]); } /** * 验证重定向URI是否安全合法 */ private function isValidRedirect($uri) { $parsed = parse_url($uri); // 检查域名是否为本站 if (!isset($parsed['host']) || $parsed['host'] !== request()->getHost()) { return false; } // 排除登录、注册等可能导致循环重定向的页面 $invalidPaths = [ route('login', [], false), route('register', [], false), route('password.request', [], false), ]; foreach ($invalidPaths as $path) { if (str_starts_with($uri, $path)) { return false; } } return true; } }
3. 适配RedirectIfAuthenticated中间件
修改app/Http/Middleware/RedirectIfAuthenticated.php,避免已登录用户访问登录页时跳错语言版本:
use Illuminate\Support\Facades\Auth; class RedirectIfAuthenticated { public function handle(Request $request, Closure $next, ...$guards) { $guards = empty($guards) ? [null] : $guards; foreach ($guards as $guard) { if (Auth::guard($guard)->check()) { $user = Auth::guard($guard)->user(); $returnUri = $request->input('return_uri'); // 优先跳转到合法的原页面 if ($returnUri && $this->isValidRedirect($returnUri)) { return redirect()->to($returnUri); } // 否则跳用户语言首页 $locale = $user->locale ?? app()->getLocale(); return redirect()->route('home', ['locale' => $locale]); } } return $next($request); } // 复用前面的isValidRedirect方法 private function isValidRedirect($uri) { $parsed = parse_url($uri); if (!isset($parsed['host']) || $parsed['host'] !== request()->getHost()) { return false; } $invalidPaths = [ route('login', [], false), route('register', [], false), route('password.request', [], false), ]; foreach ($invalidPaths as $path) { if (str_starts_with($uri, $path)) { return false; } } return true; } }
4. 解决重定向次数过多问题
之前出现循环重定向,大概率是因为没有排除登录页本身作为重定向目标。上面的isValidRedirect方法已经过滤了登录、注册等页面,避免了循环跳转。
内容的提问来源于stack exchange,提问作者Onno van der Zee
相关产品推荐
相关产品推荐

