I'm using Laravel 7.4, and I want to redirect the users to the page they came from after the login. I edited the file RedirectIfAuthenticated and added the redirect like:
return redirect()->intended(RouteServiceProvider::HOME);
But the problem is, it always redirected me to home. When I actually logged what the intended function returns, it always returns the url as website.com/email/verify. I'm 100% sure I don't redirect the users to that url, because I am logging in with an already verified user.
It might be some FW setup that I failed to notice, since I took over this project from another developer. I'll provide any more info if needed.
Check for middleware maybe you are redirecting unverified users to email/verify
Then in your LoginController create a protected function redirectTo() and return url()->previous();
Your code will look like this
protected function redirectTo()
{
return url()->previous();
}
Or
Also you can add $this->redirectTo = url()->previous() to your constructor
like this
public function __construct()
{
$this->redirectTo = url()->previous();
$this->middleware('guest')->except('logout');
}
Hope this helps
If you dump dd(session()->all()) of a so-called "intended" page, you will see the following:
As you can see, Laravel store user's previously intended page at url['intended'] array element. So to imitate this behavior manually, you have to set this value manually where needed. In this case it's LoginController:
public function showLoginForm()
{
session()->put('url.intended', url()->previous());
return view('admin.auth.login');
}
Now the original location has been stored, and later when the user log in, they will be redirected as declared in RedirectIfAuthenticated#handle:
return redirect()->intended(RouteServiceProvider::HOME);
But what if the user went to the /login page intentionally, or simply put, what if they refresh the page? url.intended will have the value of route('login'), then when user logged in, they will be redirected to login page and the infinite loop continues.
In that case, url.intended should not have any value. RouteServiceProvider::HOME value will be used as destination. There must be additional condition for that, let's say your site have login route named login:
public function showLoginForm()
{
if (($url()->previous() != route('login')) {
session()->put('url.intended', url()->previous());
}
return view('admin.auth.login');
}
Case anything unclear, you may want to have a look at similar question
Related
So in my LocaleMiddleware class (which is located in the web group of the middleware), I have the following:
if (Auth::check())
{
app()->setLocale($request->user()->getLocale()); // This just fetches the locale from the database for the given user
}
And then it just returns the next request. However, there is a slight issue for example when logging in. I need to use the return redirect()->intended(); option. This poses a problem when I have for example the following route that I point to:
https://www.example.com/es/cervezas/dos
The English variant of this url would be:
https://www.example.com/en/beers/two
My routes look like this for example:
Route::name('user.')->prefix(app()->getLocale())->group(function () {
Route::get(trans('routes.beers'), [BeersController::class, 'index'])->name('beers.index');
}
So in my routes I translate everything, and I also have slugs for each of my database models etc, which is why I always need to have the correct locale set but also I always need to have the correct locale in the url. If not I get not found exceptions when viewing specific model items or weird translations.
But one of the main problems is, when I go to the Spanish route for example (or any route for that matter in any language), after logging in, it will return the intended url/route, which will be the English one since en is the fallback locale.
So basically, what I was thinking is something along the lines of this, in my LocaleMiddleware class:
if (Auth::check())
{
app()->setLocale($request->user()->getLocale());
// Check if the segment locale is the same as the user locale
// IF NOT, redirect them
if(request()->segment(1) !== $request->user()->getLang())
{
return redirect()->route(request()->route()->getName()); // Not sure what to do here, doing this just creates an endless loop because the locale somehow was not updated yet it seems
}
}
Any ideas for a solution for this, in the LocaleMiddleware or anywhere else? Or am I going about this the wrong way entirely? Any pointers are appreciated!
Edit:
Now in my LoginController I have the following:
protected function authenticated(Request $request, $user)
{
app()->setlocale($user->getLocale());
dd(app()->getLocale()); // This is the correct locale, `es` or `nl`
dd(route('beers.index')); // This just always shows the English route
}
How come the app()->getLocale() shows the correct locale but the route is still always in the default locale? And of course, how to fix that?
Usually you have access to the user in the login function before redirecting.
In many of my projects there is an admin panel and I use the same default login endpoint. During the login process I check where the user is an admin or not and decide where to redirect him.
Here's an example of the store function in App\Http\Controllers\Auth\LoginController in a laravel 8 project:
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
if (Auth::user()->hasRole('admin')) {
return redirect()->intended(RouteServiceProvider::ADMIN_HOME);
}
return redirect()->intended(RouteServiceProvider::HOME);
}
So I believe that if you edit your redirection logic in the login controller it should work, because you have access the user, before you actually redirect him.
Can I redirect to the previous page someone if not logged in? Also, is it possible to create a hierarchy system for users?
I tried this:
if(!(Auth::check())) {
header("Location: {{ route('cooperado.index') }});
}
But i not even got an error message, just doesn't work. I'm starting at laravel so it's kind of hard to fully understand how it works.
Using Constructor in controller
You also can use middleware in order to redirect unauthenticated user back or somewhere else.
public method __construct(){
$this->middleware('auth');
}
Add this code in your controller so all methods within particular controller
-direct from route defination
Route::get('/path/',controller#method)->name('cooperado.index')->middleware('auth');
Redirection
using this method unauthenticated user will redirect to login page.
in order to edit redirection page you can change '#redirectTo' method
in
app/Http/Middleware/Authenticate.php
file.
if(!(Auth::check())) {
return redirect()->route('cooperado.index');
}
You mention in your question also wants to return previous page then use following but i'm not recommended this because if your first login effort fails then login failed' page becomes your previous page and second login effort succeeds then you are redirected to login page again because it's your previous page.
return Redirect::to(URL::previous());
You can use this. Is the easiest way to do this.
And you can also pass message, will displayed on when user redirect back from main page.
if(!Auth::check) {
return Redirect::back()->with('error','Please Login');
}
Suppose a user is looking into some section of page and he is not logged in. He than logs in through the link given in the page. How can I redirect the user to specific section that he was reading.
Note: I have already redirected the user to initial page but still can't redirect to the specific section.
Use the intended() method:
return redirect()->intended();
This method reads the url.intended value from the session and if it exists, the method redirects a user to this URL. If not, by default it redirects a user to /
To make it work with a section, use JS to get full URL:
window.location.href
Then you could make an AJAX call to save current URL to the session manually with:
session(['url.intended' => url()->full()])
Or you could put it into a hidden input and then in a LoginController get it from a request and save it to the session.
The way i did it:
In App\Http\Middleware\Authenticate.php i update the handle function like this:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect('login')->with(['lastUrl' => $request->url()]);
}
}
return $next($request);
}
The important part is return redirect('login')->with(['lastUrl' => $request->url()]);. That way i got the intended url the user tried to access before login so when i login i just redirect the user to the url he tried to access.
In case the user didn't try to access any page he is just redirected to the default welcome page.
I have a feeling this is a very dumb question and there's probably something really tiny I just overlooked, but I'm stumped anyway.
Currently, I have an app with a few pages that are protected through middleware. If the user does not meet the requirements of these middleware, they are redirected to a login page. Now after they log in, I want them to be sent back to the page they tried to visit.
I've tried numerous things to accomplish this, but none work. What I'm trying to do now is the following:
User attempts to access an admin page (for example /admin): PagesController#adminDashboard
When they access the overview() method in the controller (same as index(), but for admins), a session variable is set containing the url they tried to visit (/admin)
The user is redirected to the login page and logs in (SessionsController#create and #store)
After logging in, they are redirected to the session variable with the intended URL
This is how I tried to do it:
PagesController
public function adminDashboard()
{
$intended = '/admin';
session('intended-url', $intended);
//dd(session('intended-url');
$schools = School::all();
$articles = Article::all();
$sights = Sight::all();
return view('admin', compact('sights', 'articles', 'schools'));
}
SessionsController
public function store()
{
/*
...
*/
$intendedURL = session('intended-url');
if($intendedURL != null)
{
return redirect($intendedURL);
}
else
{
return redirect()->home();
}
Using dd() a few times here and there, I found out that it doesn't even set the session variable at the very start (commented dd() in PagesController returns null).
I've tried doing this using Session::put(), Session::set(), using square brackets as in session(['intended-url', '/admin']), but none of it gives me the result I'm looking for :(
Does anyone have any advice on how to do this, or perhaps a different way of accomplishing the same goal, but more efficiently? Thank you!
EDIT: I don't think the default Laravel redirect to intended page will work here, since I rewrote most of the login system from scratch to suit some specific needs. Unless anyone knows how that redirect works behind the scenes and I can over-/rewrite it
If you are using the default auth system, you can use this to redirect users to the page they wanted to view:
return redirect()->intended('fallback/uri');
why u are not using middleware just make new middleware
php artisan make:middleware admin
and add this code of public function handle
if (!Auth::guest() && Auth::user()->admin) {
return $next($request);
}
return redirect('/')->with('warning', 'This Area only For Admin');
add this code in kernal on protected $routeMiddleware
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\admin::class,
];
make new column in users table
$table->boolean('admin')->default(false);
now you can use your construct function
public function __construct()
{
$this->middleware('admin');
}
Note:- where u add $this->middleware('admin'); all controller will be locked for users and guest only admin can use this controller
I'm using a controlled route as such
Route::controller('company', 'CompanyController');
In this Controller i have a getLogin and postLogin function, the getLogin shows the login view. To get there i need to go to company/login
Now i'm wondering how can i redirect company/ to company/login
I have the following working but is it good practice?
Route::get('company', 'CompanyController#getLogin');
Route::controller('company', 'CompanyController');
Thank you!
In this case, index methods will respond to the root URI, so what you can do is create a getIndex() function which will return Redirect::to('company/login'). You can probably do a check on this for a logged in user first as well, for example...
public function getIndex()
{
if(!Auth::check())
return Redirect::to('company/login');
// Continue with what should happen if the user is logged in.
}
This way, when someone goes to /company, it will redirect them to login if they aren't logged in already or it will continue doing whatever you want it to do or redirect them to the same page you are redirecting people to after they login.
This also means you can do away with that Route::get() that you have setup for company.