Laravel force user to logout if deleted status - laravel

I am trying to force a logout during the login process when a user has a status flag of value 0.
Here's my login code:
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
//protected $redirectTo = '/landlords/dashboard';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
protected function redirectTo()
{
$user=Auth::user();
if($user->account_type == 1){
return '/t/dashboard';
}elseif($user->account_type==2){
return '/l/dashboard';
} else {
return '/a/dashboard';
}
}
}
It looks like Auth::user() infers that they are already logged in. How do i proceed in logging out the authenticated user and redirecting to /login if they have $user->status == 0

Just to complement #Tim Lewis answer, you can also avoid the user login if doesn't have a status == 1, adding an extra condition to the authentication query in addition to the user's e-mail and password. Specifying Additional Conditions
public function authenticate(Request $request)
{
if (Auth::attempt(['email' => $email, 'password' => $password, 'status' => 1])) {
// all ok, you can redirect the user
}
}
UPDATE
Also you can create a middleware that checks that field in the logged in user, in case the user is already logged in when the status changes:
artisan make:middleware CheckStatus
then in \app\http\Kernel.php, in the $routeMiddleware array, add:
//you can change checkStatus to canBeLogued, or whatever you want, I'm not good it english at all
'checkStatus' => \App\Http\Middleware\CheckStatus::class,
then in \app\http\Middleware\CheckStatus.php, something like this in the handle method:
if(Auth::check() && Auth::User()->status == 0)
Auth::logout();
return redirect()->to('/login')->with('warning', 'Your session has expired because your status change.');
}
return $next($request);
then, apply that middleware to the routes you want. If it's applicable to all the routes, you could do something like this in web.php
Route::group(['middleware' => 'checkStatus'], function () {
//all your protected routes
});

You can simply check $user in redirectTo():
protected function redirectTo(){
$user = auth()->user();
if($user->status == 0){
auth()->logout();
return '/login';
}
if($user->account_type == 1){
return '/t/dashboard';
} else if($user->account_type==2){
return '/l/dashboard';
} else {
return '/a/dashboard';
}
}
An argument can be made that you shouldn't let the user login if they have a status of 0, and that would simply be done by overriding the login logic. I don't personally use Laravel's default auth logic, so I can't advise on that approach, but it should be an option.

Related

Protecting Routes with Middleware in laravel

I have a project that it has two sections "admin" and "student".
I want to make a middleware that if a user who authenticated if his role was 1 automatically redirect it to admin panel and if his role was 2 automatically redirect it to student panel.
i made this middleware but when im test it i have "Too Many Rediredcts" error :
My Middleware Code :
if (auth()->check() && auth()->user()->role === 1){
return $next($request);
}else{
return redirect()->route('front.index');
}
My Routes :
How can i solve this?
I was facing the same issue and resolve it by using redirection with Url-like redirect('/admin/login'). Check and try the below code in your Laravel app.
if (auth()->check() && auth()->user()->role === 1){
return $next($request);
}else{
return redirect('/admin/login')->withErrors(['Access Denied']);
}
OR
if (auth()->check() && auth()->user()->role === 1){
return $next($request);
}else{
return redirect()->to('/admin/login')->withErrors(['Access Denied']);
}
Without seeing your middleware, it's hard to identify the problem, but the rest of your code looks fine. Try changing your your middleware to something like this:
public function handle(Request $request, Closure $next, string $roleName)
{
if (Auth::user()->isRole($roleName)) {
return $next($request);
}
abort(403);
}
We're passing a role into the middleware from the route, in your case you might pass admin. So any of your admin routes will now look like this:
Route::middleware('checkRole:admin')->prefix('admin')->group(function () {
Route::get('/', [BackController::class 'index'])->name('admin.index')
});
You are now passing a string variable to your middleware $roleName
Of course you'll also need to implement the isRole() method on your User.php Model. This will be something like:
/**
* #return HasOne
*/
public function role(): HasOne
{
return $this->hasOne(Role::class, 'id', 'role_id');
}
/**
* #return bool
*/
public function isRole($roleName): bool
{
$role = $this->role()->first();
if(!is_null($role) && $role->name == $roleName) {
return true;
}
return false;
}
I've made an assumption that you have a role_id column on your User.php Model, that you have a Role.php Model with name column which will match admin etc and you also have $routeMiddleware in Kernel.php something similar to 'checkRole' => checkRole::class,
Tested and working in Laravel 6/Laravel 8
If you wanted to test auth, I would update your route middleware to take an array, perhaps similar to:
['auth', 'checkRole:admin']
Where I have abort(403) you'll need a map of routes to roles, example: if you are an admin return redirect()->route('admin.index')

How to perform addition action on login in Laravel 5.8?

In Laravel 5.8 the Auth\LoginController is just:
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/my-team';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
On login I want to perform some custom actions for the user, but I can't figure out where I can place this code. The documentation doesn't seem to help.
Is there a method I can overwrite/extend with my own?
Laravel 5.2 used to have a login() method in the Auth controller where I could just write additional code.
You can override the login() method in LoginController. As you said, in Laravel 5.8 the login() method doesn't exist, but you can define it yourself. The newly defined login() method will override the default one and then you can do whatever extra you want to after or before the user signs in. Here is a snippet from Laracasts:
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if(Auth::attempt(['email' => $request->email, 'password' => $request->password, 'is_activated' => 1])) {
// return redirect()->intended('dashboard');
} else {
$this->incrementLoginAttempts($request);
return response()->json([
'error' => 'This account is not activated.'
], 401);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
Just go through it and see what has been done there. In short, you can modify the login() method to do whatever you want before or after a user signs in.
There are two functions provided by the AuthenticatesUsers trait. You can customize those in the login controller.
Login Form
public function showLoginForm()
{
return view('auth.login');
}
Handle Login
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
You can place these two functions in the login controller and make changes as you want.
The best place to add your custom actions is to override authenticated method in your LoginController
protected function authenticated(Request $request, $user)
{
// Your code
}
Just go to where the Illuminate\Foundation\Auth\AuthenticatesUsers trait is located and you will find all the methods you want
it's located in :
vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers
Or you can overwrite it in the LoginController to do what ever you want

Laravel 5 redirects back to home after login

I have a page where users needs to login to click on a button, if they are not logged in they are taken to the login page to login. The problem is after the login they get redirected to home page. I would like them to be redirected back to the page they were before the login but can't get it to work.
The method of the login is still 100% standard. I have tried editing this function but with no luck.
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
If you simply want to redirect the user to a different page instead of the /home, just define a
protected $redirectTo = 'your-different-route'; // i.e. '/admin'
at the top of your AuthController
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = 'admin/';
......
This should override the default route.
Anyway, in you wanna dig a bit deeper into the login system
return redirect()->intended($this->redirectPath());
is the key. Looking up to the intended method (Illuminate\Routing\Redirector) you will find something like this
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
Then, you are injecting into the intended method $this->redirectPath(), defined as
public function redirectPath()
{
if (property_exists($this, 'redirectPath')) {
return $this->redirectPath;
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
Basically, every time the user performs a login, the system checks if there's a different intended route, if not it uses the default one (/home). You can change the default redirect route into the very redirectPath() method, but care, this is part of the laravel framework, so every time laravel gets an update, you might lose your changes. A safer solution is, like I said few lines above, override the redirect in the AuthController (uploads and stuff won't affect the controller).
EDIT
If you instead want to set up a custom redirect route for each login, Laravel ships with a convenient way to accomplish that right out of the box, and, once again, we are going to use the intended() method. Wherever you redirect the user to the login page, let's say the getLogin() method, you need to change the default redirect, something like
return view('auth.login');
to
return Redirect::guest('auth.login') //assuming that auth.login is your login view
With this simple fix, you are still redirecting the user to the login page, but using the guest() method instead:
public function guest($path, $status = 302, $headers = array(), $secure = null)
{
$this->session->put('url.intended', $this->generator->full());
return $this->to($path, $status, $headers, $secure);
}
Fairly straightforward, but, beside the standard redirect to(), it sets into session the intended variable equal to the current url BEFORE the actual redirection, i.e. the page where you wanna be redirected to.This is what is gonna save your day.
Last thing, within your postLogin() method, just set
return Redirect::intended('default-route');
You need to pass a default in case an intended location isn't provided in the session. Note that this is just a safety-plus, because by default, your postLogin() already has
redirect()->intended($this->redirectPath());
It uses by default redirectPath(), but now Redirect::guest() should provide an intended value.
You could use the Redirect->back() method:
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->back();
}
Although it's generally best to handle this in the Auth middleware.
More info can be found on the Laravel website.
please check this solution you might need to add
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/player';
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
//
return redirect()->route('homePlayer') ;
}
in your LoginController.php

How to redirect intended user to a different route based on their role?

I'd like to redirect my user to different route, based on their role. I have two secured area in my app, "admin" and "dashboard". I'd like to check if user is authenticated, then redirect to intended, but if user has role editor it should be redirected to dashboard, otherwise if he has role admin should be redirected to admin area.
I'm using AuthenticatesAndRegistersUsers class in my login. I have this on my custom controller:
/**
* The default redirecTo path.
*
*/
protected $redirectTo = '/dashboard';
So when a user is authenticated it will be redirected to dashboard, but I'd like to check if the intended url is on admin group route and if user has admin role it should be redirected to admin area.
I'm using this middleware to redirect to login:
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
return $next($request);
}
You could overwrite the redirectPath method used by the trait in your AuthController to inject the logic you need. Something like this:
/**
* Get the post register / login redirect path.
*
* #return string
*/
public function redirectPath()
{
// Logic that determines where to send the user
if (\Auth::user()->type == 'admin') {
return '/admin';
}
return '/dashboard';
}
EDIT:
Laravel uses the following declaration in the AuthenticatesAndRegistersUsers trait to redirect the user after successful login:
return redirect()->intended($this->redirectPath());
This will try to redirect the user to the previously attempted URL.
If you need to redirect users to the right place when they're already logged in, that would be best done by adding more logic to your authentication middleware.
Another approach is to override authenticated method
public function authenticated()
{
if(Auth::check()) {
if(\Auth::user()->hasRole('Super Admin')) {
return redirect('/admin-dashboard');
} else {
return redirect('/user-dashbaord');
}
}
}
I use this one. You also need to modify middleware RedirectIfAuthenticated so that it won't route home. Just to different user's dashboard.
public function authenticated()
{
if($request->user()->hasRole('admin'))
{
// return redirect()->intended(route('admin.index'));
return redirect()->route('admin.index');
}
if($request->user()->hasRole('super'))
{
return redirect()->route('super.index');
}
if($request->user()->hasRole('officer'))
{
return redirect()->route('officer.index');
}
}

Laravel redirect back to original destination after login

This seems like a pretty basic flow, and Laravel has so many nice solutions for basic things, I feel like I'm missing something.
A user clicks a link that requires authentication. Laravel's auth filter kicks in and routes them to a login page. User logs in, then goes to the original page they were trying to get to before the 'auth' filter kicked in.
Is there a good way to know what page they were trying to get to originally? Since Laravel is the one intercepting the request, I didn't know if it keeps track somewhere for easy routing after the user logs in.
If not, I'd be curious to hear how some of you have implemented this manually.
For Laravel 5.3 and above
Check Scott's answer below.
For Laravel 5 up to 5.2
Simply put,
On auth middleware:
// redirect the user to "/login"
// and stores the url being accessed on session
if (Auth::guest()) {
return redirect()->guest('login');
}
return $next($request);
On login action:
// 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');
}
For Laravel 4 (old answer)
At the time of this answer there was no official support from the framework itself. Nowadays you can use the method pointed out by bgdrl below this method: (I've tried updating his answer, but it seems he won't accept)
On auth filter:
// redirect the user to "/login"
// and stores the url being accessed on session
Route::filter('auth', function() {
if (Auth::guest()) {
return Redirect::guest('login');
}
});
On login action:
// 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');
}
For Laravel 3 (even older answer)
You could implement it like this:
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();
}
Storing the redirection on Session has the benefit of persisting it even if the user miss typed his credentials or he doesn't have an account and has to signup.
This also allows for anything else besides Auth to set a redirect on session and it will work magically.
Laravel >= 5.3
The Auth changes in 5.3 make implementation of this a little easier, and slightly different than 5.2 since the Auth Middleware has been moved to the service container.
Modify the new Middleware auth redirector
/app/Http/Middleware/RedirectIfAuthenticated.php
Change the handle function slightly, so it looks like:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect()->intended('/home');
}
return $next($request);
}
TL;DR explanation
The only difference is in the 4th line; by default it looks like this:
return redirect("/home");
Since Laravel >= 5.3 automatically saves the last "intended" route when checking the Auth Guard, it changes to:
return redirect()->intended('/home');
That tells Laravel to redirect to the last intended page before login, otherwise go to "/home" or wherever you'd like to send them by default.
There's not much out there on the differences between 5.2 and 5.3, and in this area in particular there are quite a few.
I found those two great methods that might be extremely helpful to you.
Redirect::guest();
Redirect::intended();
You can apply this filter to the routes that need authentication.
Route::filter('auth', function()
{
if (Auth::guest()) {
return Redirect::guest('login');
}
});
What this method basically does it's to store the page you were trying to visit and it is redirects you to the login page.
When the user is authenticated you can call
return Redirect::intended();
and it's redirects you to the page you were trying to reach at first.
It's a great way to do it although I usually use the below method.
Redirect::back()
You can check this awesome blog.
You may use Redirect::intended function. It will redirect the user to the URL they were trying to access before being caught by the authenticaton filter. A fallback URI may be given to this
method in case the intended destinaton is not available.
In post login/register:
return Redirect::intended('defaultpageafterlogin');
Change your LoginControllers constructor to:
public function __construct()
{
session(['url.intended' => url()->previous()]);
$this->redirectTo = session()->get('url.intended');
$this->middleware('guest')->except('logout');
}
It will redirect you back to the page BEFORE the login page (2 pages back).
I have been using this for a while on my language selector code. As long as you only need to go back by just 1 page it works fine:
return Redirect::to(URL::previous());
It ain't the most powerful solution out there but it is super-easy and can help solve a few puzzles. :)
For Laravel 8
Following approach works for me for Laravel 8.
Controller based approach
/app/Http/Controllers/Auth/AuthenticatedSessionController.php
Pre-login
The intended url will be stored in the session at create :
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
session(['url.intended' => url()->previous()]);
return view('auth.login');
}
Post-login
Upon successful login, in case a intended url is available in session then redirect to it otherwise redirect to the default one :
/**
* 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('/');
this will redirect you to default page of your project i.e. start page.
For laravel 5.* try these.
return redirect()->intended('/');
or
return Redirect::intended('/');
Laravel 3
I tweaked your (Vinícius Fragoso Pinheiro) code slightly, and placed the following in 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');
}
});
And then within the my 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'));
}
Notice that the 'redirect' session data is reflashed if there is a authentication issue. This keeps the redirect intact during any login mishaps, but should the user click away at any point, the next login process is not disrupted by the session data.
You also need to reflash the data at the point of showing the login form in your AuthController, otherwise the chain is broken:
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');
}
Use Redirect;
Then use this:
return Redirect::back();
In Laravel 5.8
in App\Http\Controllers\Auth\LoginController add the following method
public function showLoginForm()
{
if(!session()->has('url.intended'))
{
session(['url.intended' => url()->previous()]);
}
return view('auth.login');
}
in App\Http\Middleware\RedirectIfAuthenticated replace " return redirect('/home'); " with the following
if (Auth::guard($guard)->check())
{
return redirect()->intended();
}
Its September 2022 now, and I would like to share what I did for the OP's questions. Please be easy on me, still noob here.
My problem : After I implement MustVerifyEmail, the above solutions did not work. I use Laravel 6.x.
So after getting headache overnight, countless mugs of coffe, finally its working now. It isn't new solution because it is a modification from previous answers.
Step 1.
Do realize that : session with name 'url.intended' is already been taken by : vendor\laravel\framework\src\Illuminate\Routing\Redirector.php
So I choose to use different name for the session which is : 'url_intended'
Step 2.
Add this line:
session(['url_intended' => url()->previous()]);
In app\Http\Middleware\Authenticate.php something like below:
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string
*/
protected function redirectTo($request)
{
session(['url_intended' => url()->previous()]);
if (! $request->expectsJson()) {
return route('login');
}
}
}
Now, here comes the key solution. Instead modifying the app\Http\Controllers\Auth\LoginController or app\Http\Middleware\RedirectIfAuthenticated.php
which did not work for me, I modify the vendor\laravel\framework\src\Illuminate\Auth\Middleware\EnsureEmailIsVerified.php
by adding the following (copy paste and slight modification from above previous answers)
if (session()->has('url_intended')) {
$redirectURL = session()->get('url_intended');
session()->forget('url_intended');
return redirect($redirectURL);
}
with full code as below :
<?php
namespace Illuminate\Auth\Middleware;
use Closure;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Redirect;
class EnsureEmailIsVerified
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $redirectToRoute
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle($request, Closure $next, $redirectToRoute = null)
{
if (! $request->user() ||
($request->user() instanceof MustVerifyEmail &&
! $request->user()->hasVerifiedEmail())) {
return $request->expectsJson()
? abort(403, 'Your email address is not verified.')
: Redirect::route($redirectToRoute ?: 'verification.notice');
}
if (session()->has('url_intended')) {
$redirectURL = session()->get('url_intended');
session()->forget('url_intended');
return redirect($redirectURL);
}
return $next($request);
}
}
its working like charm.
Update: simply create new middleware based on existing EnsureEmailIsVerified middleware, and attach it to Kernel.php :
protected $routeMiddleware = [
//other middlewares here..
'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
];
Here is my solution for 5.1. I needed someone to click a "Like" button on a post, get redirected to login, then return to the original page. If they were already logged in, the href of the "Like" button was intercepted with JavaScript and turned into an AJAX request.
The button is something like Like This Post!. /like/931 is handled by a LikeController that requires the auth middleware.
In the Authenticate middleware (the handle() function), add something like this at the start:
if(!str_contains($request->session()->previousUrl(), "/auth/login")) {
$request->session()->put('redirectURL', $request->session()->previousUrl());
$request->session()->save();
}
Change /auth/login to whatever your URL is for logging in. This code saves the original page's URL in the session unless the URL is the login URL. This is required because it appears as though this middleware gets called twice. I am not sure why or if that's true. But if you don't check for that conditional, it will be equal to the correct original page, and then somehow get chanced to /auth/login. There is probably a more elegant way to do this.
Then, in the LikeController or whatever controller you have that handles the URL for the button pushed on the original page:
//some code here that adds a like to the database
//...
return redirect($request->session()->get('redirectURL'));
This method is super simple, doesn't require overriding any existing functions, and works great. It is possible there is some easier way for Laravel to do this, but I am not sure what it is. Using the intended() function doesn't work in my case because the LikeController needed to also know what the previous URL was to redirect back to it. Essentially two levels of redirection backwards.
For Laravel 5.5 and probably 5.4
In App\Http\Middleware\RedirectIfAuthenticated change redirect('/home') to redirect()->intended('/home') in the handle function:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect()->intended('/home');
}
return $next($request);
}
in App\Http\Controllers\Auth\LoginController create the showLoginForm() function as follows:
public function showLoginForm()
{
if(!session()->has('url.intended'))
{
session(['url.intended' => url()->previous()]);
}
return view('auth.login');
}
This way if there was an intent for another page it will redirect there otherwise it will redirect home.
Laravel now supports this feature out-of-the-box!
(I believe since 5.5 or earlier).
Add a __construct() method to your Controller as shown below:
public function __construct()
{
$this->middleware('auth');
}
After login, your users will then be redirected to the page they intended to visit initially.
You can also add Laravel's email verification feature as required by your application logic:
public function __construct()
{
$this->middleware(['auth', 'verified']);
}
The documentation contains a very brief example:
https://laravel.com/docs/5.8/authentication#protecting-routes
It's also possible to choose which controller's methods the middleware applies to by using except or only options.
Example with except:
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
Example with only:
public function __construct()
{
$this->middleware('auth', ['only' => ['index', 'show']]);
}
More information about except and only middleware options:
https://laravel.com/api/5.8/Illuminate/Routing/ControllerMiddlewareOptions.html#method_except
if you are using axios or other AJAX javascript library you may want to retrive the url and pass to the front end
you can do that with the code below
$default = '/';
$location = $request->session()->pull('url.intended', $default);
return ['status' => 200, 'location' => $location];
This will return a json formatted string
If the filter is handled at the routes level, then its so simple since you just need to attach an auth middleware to your original link. When a user successfully pass through the middleware check (means they login), they are automatically redirected to the intended destination. For example, you can do this instead of checking authentication in the controller
Route::get('/appointments',[AppointmentsController::class,'appointments'])->middleware(['auth'])->name('appointments');
Did you try this in your routes.php ?
Route::group(['middleware' => ['web']], function () {
//
Route::get('/','HomeController#index');
});
// Also place this code into base controller in contract function, because ever controller extends base controller
if(Auth::id) {
//here redirect your code or function
}
if (Auth::guest()) {
return Redirect::guest('login');
}
For Laravel 5.2 (previous versions I did not use)
Paste the code into the file app\Http\Controllers\Auth\AurhController.php
/**
* Overrides method in class 'AuthenticatesUsers'
*
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
/**
* seve the previous page in the session
*/
$previous_url = Session::get('_previous.url');
$ref = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
$ref = rtrim($ref, '/');
if ($previous_url != url('login')) {
Session::put('referrer', $ref);
if ($previous_url == $ref) {
Session::put('url.intended', $ref);
}
}
/**
* seve the previous page in the session
* end
*/
return view('auth.login');
}
/**
* Overrides method in class 'AuthenticatesUsers'
*
* #param Request $request
* #param $throttles
*
* #return \Illuminate\Http\RedirectResponse
*/
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
/*return to the previous page*/
return redirect()->intended(Session::pull('referrer'));
/*return redirect()->intended($this->redirectPath()); /*Larevel default*/
}
And import namespace: use Session;
If you have not made any changes to the file app\Http\Controllers\Auth\AurhController.php, you can just replace it with the file from the GitHub
Laravel 5.2
If you are using a another Middleware like Admin middleware you can set a session for url.intended by using this following:
Basically we need to set manually \Session::put('url.intended', \URL::full()); for redirect.
Example
if (\Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
\Session::put('url.intended', \URL::full());
return redirect('login');
}
}
On login attempt
Make sure on login attempt use return \Redirect::intended('default_path');
Larvel 5.3 this actually worked for me by just updating LoginController.php
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\URL;
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
Session::set('backUrl', URL::previous());
}
public function redirectTo()
{
return Session::get('backUrl') ? Session::get('backUrl') : $this->redirectTo;
}
ref: https://laracasts.com/discuss/channels/laravel/redirect-to-previous-page-after-login
I am using the following approach with a custom login controller and middleware for Laravel 5.7, but I hope that works in any of laravel 5 versions
inside middleware
if (Auth::check()){
return $next($request);
}
else{
return redirect()->guest(route('login'));
}
inside controller login method
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return redirect()->intended('/default');
}
If you need to pass the intented url to client side, you can try the following
if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) {
$intended_url= redirect()->intended('/default')->getTargetUrl();
$response = array(
'status' => 'success',
'redirectUrl' => $intended_url,
'message' => 'Login successful.you will be redirected to home..', );
return response()->json($response);
} else {
$response = array(
'status' => 'failed',
'message' => 'username or password is incorrect', );
return response()->json($response);
}
First, you should know, how you redirect user to 'login' route:
return redirect()->guest('/signin');
Not like this:
return redirect()->intended('/signin');
For Laravel 5.7, You need to make change into:
Middleware>RedirectIfAuthenticated.php
Change this:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/admin');
}
return $next($request);
}
To this:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/yourpath');
}
return $next($request);
}
return redirect('/yourpath');

Resources