Check for referrer or use a query string entry to navigate back, like this site does.
L5.2 Redirect to page where login button was clicked
Really common situation but i cant find any good answer:
on my site i go to some inner page and press login button. how do i redirect back to this page after login? it redirects to home page or to static $redirectPath if set
@bashy this site uses ajax but i need separate login page. if u try to use https://laracasts.com/login u will be redirected to dashboard after login or main page if already logged
Yes the old site had a query string for it but now it's an AJAX call via popup. This is the query string from the old login;
https://laracasts.com/login?return=https://laracasts.com/discuss
I guess you have to use : return back();
@bashy how to use this query actually? @AkiyamaSmart where should i use this?
you use it in the AuthController, I guess it should be postLogin method
You can add an authenticated method to your AuthController, but by the time return back() is called, you have lost the page you were on (it redirects to the login page). Taylor includes a check to see if there is an authenticated method in the class and if there is, it gets called, otherwise it calls Intended()
public function authenticated($request,$user)
{
return back();
}
Perhaps the previous page URI can be pushed to the session in the auth controller constructor, and then grabbed in the authenticated method?
This seems to work;
Assuming you are on 5.2 and using the built in Auth controller.
Add the following two functions to your app\Http\Controllers\Auth\AuthController
public function showLoginForm()
{
if(!session()->has('from')){
session()->put('from', url()->previous());
}
return view('auth.login');
}
public function authenticated($request,$user)
{
return redirect(session()->pull('from',$this->redirectTo));
}
These two will override functionality in the AuthenticatesUsers Trait
When the login form is shown, it pushes the previous URL to the session. When the user is authenticated, it gets the previous URL back from session (clearing it in the process) and then redirects to it. If for some reason the session variable is not set then a default is used.
The check when pushing to the session is to ensure we don't override the value since the form is also shown when you get the username or password wrong.
The added authenticated method is also a good place to put a 'Logged In' flash message.
@Snapey yes it works ty, is it ok to place session put in login view to prevent overriding showLoginForm?
@mineass sorry, not sure what you mean?
Better to keep it all in one place I think?
Its only a small function that you are replicating.
@Snapey true, ty
Hi Snapey,
I have your logic working. Thanks for that. However, there is a small issue. If I login from the welcome page, it redirects me back to the login page but the header content for login, register doesn't change to my name with logout option.
In app.blade.php under layouts, I have the following laravel default code
@if (Auth::guest())
<li><a href="{{ url('/login') }}">Login</a></li>
<li><a href="{{ url('/register') }}">Register</a></li>
@else
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
{{ Auth::user()->name }} <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="{{ url('/profile') }}" ><i class="fa fa-btn fa-user"></i> My Profile</a></li>
<li><a href="{{ url('/logout') }}"><i class="fa fa-btn fa-sign-out"></i>Logout</a></li>
</ul>
</li>
@endif
Yet it is not able to change to show logged in user's name with logout option in dropdown.
The flow seems to work correctly from any other page in app but its not changing name in welcome view even though user is logged in. Not sure why its happening. Did you face the same issue?
are you working with v5.2 ?
if so, check your routes file. Since when logging in, sessions are used. But for working with sessions, the route has to be in the default web middleware group. Outside this group (among others) sessions are ignored. That's a new feature of v5.2
ie move your welcome route into the web middleware and you're all fine:
Route::group(['middleware' => ['web']], function () {
Route::get('/', function () {
return view('welcome');
});
});
Why not just use core intended ?
public function showLoginForm()
{
session()->put('url.intended', url()->previous());
return view('auth.login');
}
Thanks. It worked for me. Yeah somehow I had the welcome route outside of the web middleware group.
Thanks again.
yes, thats the default install in 5.2, (welcome page does not start the session) and I am sure it's going to catch loads of people out.
@bestmomo, I thought about intended, but where it seems to go wrong is when you fail the login form and get redirected (correctly) back to the login form for another go.
Usually, I will invoke login by directing the user to a protected page (for instance Login on the Nav points to /dashboard) and then let the auth middleware catch it and redirect to intended. But in this case, the OP wanted to be directed back to the same page the user was on when they clicked Login.
When Login fails user is just redirected back (intended is only used with login success) :
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $response
* @return \Illuminate\Http\Response
*/
protected function sendFailedLoginResponse(Request $request)
{
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}
@Bestmomo Yes, I know
The question was how to redirect to the page you started from. This is NOT the intended page. Intended is where you were going when middleware intercepted the request.
Exactly, intended is where you were going when middleware intercepted the request but what is done is only save url in session in 'url.intended'. So it's not a bad idea to use it because in AuthenticatesUsers trait redirection is done with intended.
Or also you can do return \Redirect::back();
No, with back() you only return to login form, he wants the previous one.
@bestmomo OK, thankyou, I now understand your point.
Setting the url.intended session property means that only one method is required to achieve the same result since redirecting to url.intended is already performed after successful login.
Perhaps the only thing I would change is to check if intended was already set. This would cover both situations where you call Login directly and expect to return to the same page, or where you call another page that is protected by auth middleware and the flow is intercepted. In this latter case, you want to forward to the intended page and not back to previous.
Your solution has a problem similar to what I faced originally. If the login form is failed then previous becomes back and therefore intended is overwritten with back on the second visit to the login page. So if the password is wrong then you lose the original URL.
Amended version seems to work for all situations;
add the following in app\Http\Controllers\Auth\AuthController.php
public function showLoginForm()
{
if(!session()->has('url.intended')) {
session()->put('url.intended', url()->previous());
}
return view('auth.login');
}
no other changes are required.
@Snapey Hey. Thx for your input. Your answer helped me out.
I wanted to get your feedback, though, if you're up for it.
I took the ideas on this page and wrapped them up in a middleware that I added to the end of my "web" middleware stack:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpFoundation\Response;
class PersistIntendedUrlOnLogin
{
public function handle(Request $request, Closure $next): Response
{
if (Route::is('login') && (! session()->has('url.intended'))) {
session()->put('url.intended', url()->previous());
}
return $next($request);
}
}
I thought it was pretty simple and required less impact/effort, but I wanted to see if I was missing anything.
Any feedback -- from anyone...! -- would be welcome. 🤓
Thx.
Now it's perfect ;)
I case anyone needs this in L5.1, this is working, both methods go in the AuthController.php:
/**
* Show the application login form.
*
* @return \Illuminate\Http\Response
*/
public function getLogin()
{
if(!session()->has('from')){
session()->put('from', redirect()->back()->getTargetUrl());
}
if (view()->exists('auth.authenticate')) {
return view('auth.authenticate');
}
return view('auth.login');
}
/**
* @return Redirect
*/
protected function authenticated()
{
return redirect(session()->pull('from',$this->redirectPath));
}
hello all, another question for redirect. My problem is,
- fill registration form and submit.
- After submit redirect to thank you page from auth/register . such as (abc.com/thankyou)
ok that's fine. but,
- Now from thankyou, after 5sec. or 10sec. autometic redirect to login page which is auth/login.
please tell me how do i do that?????
@ramivy Please submit a new question
I have chased the default route one by one. My solution is: Leave all the default code unchanged, but add the following code to LoginController, RegisterController, and ResetPasswordController:
protected function redirectTo()
{
return session()->pull('url.intended', '/');
}
redirectTo() is also documented at https://laravel.com/docs/5.5/authentication#included-authenticating
I have tried to put the previous URL with key "url.intended", the value used to null after login, I have used other key name instead of "url.intended" (like "url.back") it works fine.
if(!session()->has('url.back')) { session()->put('url.back', url()->previous()); }
Please or to participate in this conversation.