I have a weird behaviour with the Laravel Middleware, surely because of some lack of misunderstanding... ^^
My Middleware does a route redirection if the requirement is KO. And it works well (or not? lol), except when I hit the protected route manually.
IE on the left menu, when I hit the ajax link to /home, if the requirement is not met, then I got a 302 response instead of the redirection as expected.
My unprotected route:
Route::get('/some-redirection/url', 'Controller#getRedirectIndex')->name('getRedirectIndex');
My protected route:
Route::group(['middleware' => ['isOK']], function(){
Route::get('/home', 'NavController#getHome')->name('getHome');
});
My Middleware:
class User2Redirect {
public function handle($request, Closure $next) {
$model_logic = Model::where(...)->first();
if ($model_logic->isEmpty()) {
return redirect()->route('getRedirectIndex');
}
return $next($request);
}
}
My left menu is a regular load ajax (ie. $(div_id).load('/home'))
Why do I get the 302 response when I hit manually the link /home?
register your middleware in kernel under protected $routeMiddleware = [] .
Related
I am trying to achieve this using middleware
web.php
Route::get('/test', 'TestController#index')->middleware('TestLogin');
redirect to /test if session is found
Route::get('/test1', 'TestController#index1')->middleware('TestLogin');
redirect to test1 if session is set
Middleware -TestLogin
public function handle($request, Closure $next)`
{
if($request->session()->get('Username'))
{
return redirect()->route(\);
// what to write here to redirect to the path its being called from
}
return redirect()->route('login');
}
don't want to use default auth middleware
Your middleware is suppose to check the login (session), if it is not found then redirect to login page otherwise it should pass the request. Something like this:
public function handle($request, Closure $next)
{
// No login session, redirect
if(!$request->session()->get('Username'))
{
return redirect()->route('login');
}
// Pass the request down the rest of pipeline
return $next($request);
}
You should consider to use built in authentication system in Laravel itself, it will save you lots of code and you can be sure the auth is handled correctly in security point of view.
i'm using laravel 6 and have 2 route in my app; index and dashboard.
My routes/web is:
Auth::routes();
Route::middleware(['auth'])->group(function () {
Route::get('/index', 'todoApp\TodoController#index')->name('index');
Route::get('/dashboard', 'todoApp\Dashboard#dashboard')->name('dashboard');
});
i added dashboard route recently.
Auth::user() is null when i dump it in dashboard route but doesn't in index. What's the
Your Controller is instantiated before the middleware stack has ran; this is how Laravel can know what middleware you have set via the constructor. Because of this you will not have access to the authenticated user or sessions at this point. Ex:
public function __construct()
{
$this->user = Auth::user(); // will always be null
}
If you need to assign such a variable or access this type of information you would need to use a controller middleware which will run in the stack after the StartSession middleware:
public function __construct()
{
$this->middleware(function ($request, $next) {
// this is getting executed later after the other middleware has ran
$this->user = Auth::user();
return $next($request);
});
}
When the dashboard method is called, the middleware stack has already passed the Request all the way through to the end of the stack so all the middleware needed for Auth to be functioning and available has already ran at that point which is why you have access to Auth::user() there.
I think that this has something to do with the 'web' middleware. If you take a look into the Kernel.php (In app\Http) you will find the web middleware group.
This will show you that it actually calls a middleware called StartSession. Based on your route file (where web is not included as a middleware) I would think that you don't have a session in your Controller and there for no access to it.
I don't quite understand why this only happens in your /dashboard route, because the issue should also be in your /index route (unless you added the web middleware somewhere in your TodoController).
I think that this should do the trick:
Route::middleware(['web', 'auth'])->group(function () {
Route::get('/index', 'todoApp\TodoController#index')->name('index');
Route::get('/dashboard', 'todoApp\Dashboard#dashboard')->name('dashboard');
});
If you fire php artisan make:auth command.
It's doesn't matter where you define because of it's only define auth route
Route::middleware(['auth'])->group(function () {
Route::get('/index', 'todoApp\TodoController#index')->name('index');
Route::get('/dashboard', 'todoApp\Dashboard#dashboard')->name('dashboard');
});
Auth::routes();
I have a Laravel routing file (web.php) like so:
Route::group(['middleware' => ['auth']], function () {
Route::get('/', function () {
return 'Hello World';
});
});
Route::get('/', 'Auth\LoginController#showLoginForm')->name('login');
In my application the unauthenticated homepage must go to the login screen. When authenticated, the homepage changes. However, if I run this code and login - I get an infinite redirect because the LoginController has this line:
protected $redirectTo = '/';
So basically, even thought Laravel should read the routes file top to bottom, it seems this isn't applying in my case (maybe because of the ::group()) or I am doing something wrong.
How can I accomplish a homepage that goes to the login form while also redirecting back to the same url (/) for authenticated users for a different authenticated view (and no redirect loop).
Thanks!
I would handle this inside a guest middleware that checks for an authenticated user. For this case you'll want an authenticated guard check first:
use Illuminate\Contracts\Auth\Guard;
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/home');
}
return $next($request);
}
Apply the guest middleware to the login endpoint:
Route::get('/', 'Auth\LoginController#showLoginForm')
->middleware('guest')
->name('login');
Note: Only apply the guest middleware to guest routes, otherwise you run the risk of redirect loops.
Why not handle this in your view?
You can simply remove one of the route declaration from your web.php.
Then go ahead with conditional rendering.
#auth
Show Home page
#endauth
#guest
Show Login
#endguest
I guess middleware does not prevent request from hitting the routes,
It rather prevents request from going through.
You can't use middleenter code hereware to decide with route to hit, thereby the loop.
When you're thinking in terms of bottom down processing, laravel has already registered every declared routes.
I'm struggling to get the login/register pages to redirect the user if already logged in.
in routes.php
Route::group(array('before' => 'auth'), function()
{
Route::get('hud', 'HomeController#index')->name('hud');
Route::get('search', 'HomeController#search')->name('search');
Route::get('profile', 'UsersController#index')->name('profile');
Route::get('clients', 'ClientsController#index')->name('clients');
Route::delete('clients/{id}', 'ClientsController#destroy');
Route::resource('projects', 'ProjectsController', array('only' => array('show')));
});
I've tried no_auth and it just breaks. Am I missing something?
You should set the redirect path for when a given visitor is authenticated user.
You can do so in: App\Http\Middleware\RedirectIfAuthenticated
Example:
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/dashboard');
}
return $next($request);
}
Stackoverflow: laravel redirect if logged in
You want to redirect already registered user to Homepage whenever they try to hit /login.
Here's how laravel tries to achieve that.
Firstly this is achieved through App\Http\Middleware\RedirectIfAuthenticated.
However a key to this middleware is registered to guest in this file app\Http\Kernel.php under array protected $routeMiddleware.
Then in your login controller presumably at app\Http\Controllers\Auth\LoginController.php
In the construct method, We have something like this:
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
I have changed the protected $redirectTo = '/tasks'; in both the LoginController and RegisterController.
Also, I have changed the redirect path in the middleware RedirectIfAuthenticated as follows:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/tasks');
}
return $next($request);
}
Even though I have done these changes, nothing works, and the pages are redirected to the /login path.
That's because $redirectTo will take effect after you have logged in. First of all you need to login. That's why it's sending you to /login path. So if you want to change where it redirects after Login or Registration, you change those $redirectTo properties. If you don't want a user to login at all, you should remove the auth middleware for that route.
EDIT:
So what you have missed is that laravel redirects you back to the intended page and if there is none it will redirect to $redirectTo. So if you try to go to homepage and that needs authenticated user, after login it redirects back to the homepage and not /tasks because that's where you were trying to go. If you want to always redirect to that path and not to intended path you can do something as below.
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return redirect()->to($this->redirectTo);
}
Add this code to your LoginController and you will always be redirected to $redirectTo.
After seeing your code, I got that your IF statement is not returning true. You have to first see, what is it returning. Also, redirect to your desired location without any condition just to test the code.
Also, I am using this code for redirection after login in my application.
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/home');
}
return $next($request);
}