这似乎是一个相当基础的流程,而且 Laravel
有许多好的解决方案来处理基本的事情,我觉得我可能遗漏了什么。
用户点击需要身份验证的链接。 Laravel 的 auth 过滤器启动并将用户路由到登录页面。 用户登录后,再次访问之前被“auth”过滤器拦截的原始页面。
有没有一种很好的方法可以知道他们最初想要进入哪个页面?由于 Laravel 拦截请求,我不知道它是否在某处记录以便用户登录后轻松路由。
如果没有,我很想听听你们中的一些人如何手动实现这一点。
请查看下面Scott的答案。
简单来说,
在身份验证中间件上:
// redirect the user to "/login"
// and stores the url being accessed on session
if (Auth::guest()) {
return redirect()->guest('login');
}
return $next($request);
在登录操作中:
// redirect the user back to the intended page
// or defaultpage if there isn't one
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return redirect()->intended('defaultpage');
}
在回答时,框架本身没有官方支持。现在您可以使用下面所述的方法:bgdrl指出的方法此方法:(我尝试更新他的答案,但似乎他不接受)
关于身份验证过滤器:
// redirect the user to "/login"
// and stores the url being accessed on session
Route::filter('auth', function() {
if (Auth::guest()) {
return Redirect::guest('login');
}
});
在登录操作中:
// redirect the user back to the intended page
// or defaultpage if there isn't one
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return Redirect::intended('defaultpage');
}
您可以像这样实现它:
Route::filter('auth', function() {
// If there's no user authenticated session
if (Auth::guest()) {
// Stores current url on session and redirect to login page
Session::put('redirect', URL::full());
return Redirect::to('/login');
}
if ($redirect = Session::get('redirect')) {
Session::forget('redirect');
return Redirect::to($redirect);
}
});
// on controller
public function get_login()
{
$this->layout->nest('content', 'auth.login');
}
public function post_login()
{
$credentials = [
'username' => Input::get('email'),
'password' => Input::get('password')
];
if (Auth::attempt($credentials)) {
return Redirect::to('logged_in_homepage_here');
}
return Redirect::to('login')->with_input();
}
在5.3中进行的认证更改使其实现变得更加容易,并且与5.2略有不同,因为Auth中间件已被移动到服务容器中。
/app/Http/Middleware/RedirectIfAuthenticated.php
稍微改变句柄函数的写法,使其看起来像这样:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect()->intended('/home');
}
return $next($request);
}
唯一的区别在于第四行;默认情况下它看起来像这样:
return redirect("/home");
Laravel >= 5.3 在检查身份验证保护时会自动保存最后一个“预期”的路由,因此它更改为:
return redirect()->intended('/home');
这告诉 Laravel 在登录前重定向到最后一个意图页面,否则默认跳转到 "/home" 或者你想要的任意页面。
关于 Laravel 5.2 和 5.3 之间的区别并没有太多相关资料,而在这个领域尤其如此。
return redirect()->intended(RouteServiceProvider::HOME);
将您的主页路径统一放在一个位置。 - Mateusz我发现了这两种非常有效的方法,对你可能非常有帮助。
Redirect::guest();
Redirect::intended();
您可以将此过滤器应用于需要进行身份验证的路由。
Route::filter('auth', function()
{
if (Auth::guest()) {
return Redirect::guest('login');
}
});
这个方法的基本思想是存储您尝试访问的页面,并将您重定向到登录页面。
当用户经过身份验证后,您可以调用
return Redirect::intended();
并且它会将您重定向到您最初尝试访问的页面。
这是一个很好的方法,尽管我通常使用下面的方法。
Redirect::back()
您可以查看这篇很棒的博客。
return Redirect::intended('defaultpageafterlogin');
将您的LoginControllers构造函数更改为:
public function __construct()
{
session(['url.intended' => url()->previous()]);
$this->redirectTo = session()->get('url.intended');
$this->middleware('guest')->except('logout');
}
它会将您重定向回登录页面之前的页面(向后2页)。
我在我的语言选择器代码中使用了这个功能一段时间了。只要你只需要回到上一页,它就能正常工作:
return Redirect::to(URL::previous());
虽然它不是最强大的解决方案,但易于使用且可以帮助解决一些难题。 :)
下面的方法对于 Laravel 8 对我很有效。
/app/Http/Controllers/Auth/AuthenticatedSessionController.php
预期的 URL 将在创建会话时存储:
/**
* Display the login view.
*
* @return \Illuminate\View\View
*/
public function create()
{
session(['url.intended' => url()->previous()]);
return view('auth.login');
}
登录成功后,如果会话中有预定的URL,则重定向到该URL,否则重定向到默认URL:
/**
* Handle an incoming authentication request.
*
* @param \App\Http\Requests\Auth\LoginRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
//in case intended url is available
if (session()->has('url.intended')) {
$redirectTo = session()->get('url.intended');
session()->forget('url.intended');
}
$request->session()->regenerate();
if ($redirectTo) {
return redirect($redirectTo);
}
return redirect(RouteServiceProvider::HOME);
}
return Redirect::intended('/');
对于 Laravel 5.*,请尝试以下方法。
return redirect()->intended('/');
return Redirect::intended('/');
我稍微调整了您(Vinícius Fragoso Pinheiro)的代码,并将以下内容放置在filters.php中。
Route::filter('auth', function()
{
// If there's no user authenticated session
if (Auth::guest()) {
// Flash current url to session and redirect to login page
Session::flash('redirect', URL::full());
return Redirect::guest('login');
}
});
然后在我的 AuthController.php 文件中:
// Try to log the user in.
if (Auth::attempt($userdata)) {
if ($redirect = Session::get('redirect')) {
return Redirect::to($redirect);
} else {
// Redirect to homepage
return Redirect::to('your_default_logged_in_page')->with('success', 'You have logged in successfully');
}
} else {
// Reflash the session data in case we are in the middle of a redirect
Session::reflash('redirect');
// Redirect to the login page.
return Redirect::to('login')->withErrors(['password' => 'Password invalid'])->withInput(Input::except('password'));
}
请注意,如果出现身份验证问题,会重新引用'redirect'
会话数据。这在任何登录问题期间保持重定向不变,但是如果用户在任何时候点击离开,下一个登录过程不受会话数据干扰。
您还需要在AuthController
中显示登录表单的位置刷新数据,否则链路将被中断:
public function showLogin()
{
// Reflash the session data in case we are in the middle of a redirect
Session::reflash('redirect');
// Show the login page
return View::make('auth/login');
}