I have created a custom middleware and i am checking if the password field is null and redirect user to change the password but it give me redirection error, any one can help? Let me add more details i want user to redirect to /change-password if the password field is empty
so here's the whole process.
user verify the email, redirect to /change-password route instead of dashboard if password field in the database is empty other wise we redirect them to dashboard. Users shouldn't access any route until they didn't update the password.
Remember i am using laravel breeze for auth
Middleware code:
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ChangePasswordMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
$user = Auth::user();
if (empty($user->password)){
return redirect()->route('patient.password');
} else{
return redirect()->intended(RouteServiceProvider::HOME);
}
return $next($request);
}
}
My Routes:
Route::middleware(['auth', 'verified', 'changepassword'])->group(function (){
Route::get('/change-password', [PatientsController::class, 'passwordView'])->name('patient.password');
Route::get('/dashboard', [PatientsController::class, 'index'])->name('patient.dashboard');
Route::get('pricing', [PatientsController::class, 'pricing'])->name('patient.pricing');
});
changepassword is registered in my kernel.php and it's a custom middleware.
i have tried to create a different group for routes but it still doesn't work, i want changepassword middleware to force use to change the password and other routes shouldn't work until the password field is updated
As mentioned in the comments, the middleware is being called over and over because the password is empty. Hence, the issue of too many redirects. Your routes must ignore the route for /change-password.
Route::middleware(['auth', 'verified', 'changepassword'])->group(function (){
Route::get('/change-password', [PatientsController::class, 'passwordView'])
->name('patient.password')
->withoutMiddleware([\App\Http\Middleware\ChangePasswordMiddleware::class]);
...
...
});
After this your too many redirects problem should go away.
Also, make sure your if/else logic is correct in the handle() method. The else logic looks odd to me.
Try
public function handle(Request $request, Closure $next)
{
$user = Auth::user();
if (empty($user->password)){
abort(302, 'Please change your password', ['Location' => route('patient.password')]);
}
return $next($request);
}
If the password is empty, it automatically redirects to /change-password route.
In my project created with Laravel 8 with vue+ inertia + fortify package, I use two guards one for normal users and one for admins. but there only have one login view redirect.
I just want to show different login to normal users and another login to admins. it should detect by middleware used in the route. I can filter it, if I can get the requested guard name from there.
Here is my example route:
<?php
//'auth:users' is normal users guard
Route::group(['middleware' => 'auth:users'], function () {
Route::prefix('/account')->name('account.')->group(function () {
Route::get('/', [AccountController::class, 'index'])->name('index');
});});
//'auth:web' is admin users guard
Route::group(['middleware' => 'auth:web'], function () {
Route::prefix('/admin')->name('admin.')->group(function () {
Route::prefix('/account')->name('account.')->group(function () {
Route::get('/', [AdminAccountController::class, 'index'])->name('index');
});
});
});
auth middleware:
<?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|null
*/
protected function redirectTo($request)
{
// both request coming to here i want get middlware name from here
// if('auth:web'){
//redirect to adimin login
// }else{
//redirect to userlogin
//}
if (! $request->expectsJson()) {
return route('admin.login');
}
}
}
You can get a list of all middleware used for the current route using request()->route()->computedMiddleware so your code would be:
<?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|null
*/
protected function redirectTo($request)
{
if ($request->route() && in_array('auth:web', $request->route()->computedMiddleware??[]) {
// redirect to admin login
} else {
// redirect to admin login
}
if (! $request->expectsJson()) {
return route('admin.login');
}
}
}
When I try to access any route under the auth middleware I get redirected to a login route.
Route::group(['middleware' => 'auth'], function () {
Route::get('area-cliente/resumo', 'AreaClienteController#resumo')->name('area_cliente_resumo');
});
this is my authenticate 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)
{
if(Auth::guard('cliente')->guest())
{
return route('registrar');
}
return next($request);
}
}
I cannot see where the code that is redirecting to a login route is located and I don't know why either, since the user is apparently logged using the code below;
public function logar(Request $request) {
$credenciais = [
"email" => $request->email,
"senha" => $request->senha
];
$results = auth()->guard('cliente')->login(Cliente::find(1));
if(auth()->guard('cliente')->check()){
//I am able to echo the name of the user
//echo auth()->guard('cliente')->user()->name
return redirect()->route('home');
}
else{
echo "no";
}
}
I've also tried to clean (remove all functions) of the RedirectIfAuthenticated and authenticate middleware but the behavior of the application doesn't change, I still being redirected to a login page on the routes under the auth middleware.
I have a Laravel API (actually a Lumen API) serving a VueJS front-end. The Vue app allows users to login to Google. The Google token is then sent back to the Lumen API, which verifies the token with Google, then verifies that the email address is a valid user. Then it generates a token, stores that in the DB with the user and returns the user object.
I'm not using Passport or jwt-auth or anything like that. So now, how do I go about using the default Auth middleware to verify the token header that the (now logged in) user will be returning with every request? (i.e. is the token in the DB and is it expired?). And is there a way to do this more efficiently, so Laravel caches the valid tokens and doesn't have to hit the DB for every request?
You can use the Authentication Middleware. Pass with your request an api_token. A more detailed answer can be found here.
Add a api_token column to your User table.
$table->string('api_token', 60)->unique();
Have an authentication middleware as such:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
return $next($request);
}
}
And use Route Group
Route::group(['middleware' => 'auth:api'], function () {
Route::resource('api/v1/foo/bar', 'API\FooBarController');
}
When user logs in and is authenticated, I use Auth::user()->username; to show username of user on dashboard. However, for some reason when session expires the class Auth doesn't seem to work and dashboard page throws error as trying to get property of non-object for Auth::user()->username;. How can I redirect the user back to the login page when he clicks any link or refreshes the page after the session has expired?
I tried the Authenticate.php middleware but it always redirects back to login page,whatever you put the credentials either correct or incorrect.However,when I don't use this middleware it logins the user.Am I missing something?
Route.php
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
/*
Actions Handled By Resource Controller
Verb Path Action Route Name
GET /photo index photo.index
GET /photo/create create photo.create
POST /photo store photo.store
GET /photo/{photo} show photo.show
GET /photo/{photo}/edit edit photo.edit
PUT/PATCH /photo/{photo} update photo.update
DELETE /photo/{photo} destroy photo.destroy
Adding Additional Routes To Resource Controllers
If it becomes necessary to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource:
Route::get('photos/popular', 'PhotoController#method');
Route::resource('photos', 'PhotoController');
*/
// Display all SQL executed in Eloquent
// Event::listen('illuminate.query', function($query)
// {
// var_dump($query);
// });
define('ADMIN','admin');
define('SITE','site');
Route::group(['namespace' => ADMIN], function () {
Route::get('/','UserController#showLogin');
});
////////////////////////////////////Routes for backend///////////////////////////////////////////////////
Route::group(['prefix' => ADMIN,'middleware' => 'auth'], function () {
Route::group(['namespace' => ADMIN], function () {
//Route::get('/','EshopController#products');
//sumit routes for user registration
//Route::resource('users','UserController');
Route::get('/users/destroy/{id}','UserController#destroy');
Route::get('UserProf','UserController#userProf');
Route::get('users','UserController#index');
Route::get('/users/create','UserController#create');
Route::get('/users/adminEdit/{id}','UserController#adminEdit');
Route::post('/users/adminUpdate','UserController#adminUpdate');
Route::post('/users/store','UserController#store');
Route::get('/users/edit/{id}','UserController#edit');
Route::post('/users/update/{id}','UserController#update');
//airlines route
Route::get('airlines','AirlinesController#index');
Route::get('/airlines/create','AirlinesController#create');
Route::post('/airlines/store','AirlinesController#store');
Route::get('/airlines/edit/{id}','AirlinesController#edit');
Route::post('/airlines/update','AirlinesController#update');
Route::get('/airlines/destroy/{id}','AirlinesController#destroy');
//end sumit routes
//flight routes
Route::get('flights','FlightController#index');
Route::get('showFlightBook','FlightController#showFlightBook');
Route::get('flights/create','FlightController#create');
Route::post('flights/store','FlightController#store');
Route::get('flights/book','FlightController#book');
Route::get('flights/edit/{id}','FlightController#edit');
Route::post('flights/update','FlightController#update');
Route::get('flights/destroy/{id}','FlightController#destroy');
//Route::resource('flight','FlightController');
//hotels route
Route::get('hotels','HotelsController#index');
Route::get('/hotels/create','HotelsController#create');
Route::post('/hotels/store','HotelsController#store');
Route::get('/hotels/edit/{id}','HotelsController#edit');
Route::post('/hotels/update','HotelsController#update');
Route::get('/hotels/destroy/{id}','HotelsController#destroy');
//end sumit routes
//book-hotel routes
Route::get('hotel-book','HotelBookController#index');
Route::get('showHotelBook','HotelBookController#showHotelBook');
Route::get('hotel-book/create','HotelBookController#create');
Route::post('hotel-book/store','HotelBookController#store');
Route::get('hotel-book/book','HotelBookController#book');
Route::get('hotel-book/edit/{id}','HotelBookController#edit');
Route::post('hotel-book/update','HotelBookController#update');
Route::get('hotel-book/destroy/{id}','HotelBookController#destroy');
//Route::resource('hotel','HotelController');
//close flight routes
//for admin login
//Route::get('initlogin','UserController#lgnPage');
Route::get('login','UserController#showLogin');
// Route::get('privilegeLogin','UserController#privilegeLogin');
// Route::post('privilegeCheck','UserController#privilegeCheck');
Route::post('login','UserController#doLogin');
Route::get('/dashboard','DashController#index');
Route::get('logout','UserController#doLogout');
//user login
//Route::get('userLogin','UserController#showUserLogin');
//Route::post('userLogin','UserController#doUserLogin');
Route::get('/userDashboard','DashController#userIndex');
Route::get('Logout','UserController#doUserLogout');
//password reset
Route::get('forget-pass','UserController#showReset');
//Route::get('home', 'PassResetEmailController#index');
});
});
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Authenticate.php:
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate {
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
// return redirect()->guest('auth/login');
return redirect()->guest('/');
}
}
return $next($request);
}
}
All you have to do is just put this constructor at the top of the controller for your dashboard. It seems Laravel has a middleware that handles this already. At least I can confirm from 5.4 and up.
public function __construct()
{
$this->middleware('auth');
}
If the session expires then you can redirect to log in like as
open this file app/Exceptions/Handler.php add this code
public function render($request, Exception $exception)
{
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return redirect('/login');
}
return parent::render($request, $exception);
}
If you want a middleware to be run during every HTTP request to your application, simply list the middleware class in the $middleware property of your app/Http/Kernel.php class.
So, to protect every route from being accessed without authentication do this
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
'App\Http\Middleware\Authenticate',// add this line according to your namespace
];
it will redirect the user if not logged in. UPDATE Keep in mind that adding auth middleware as global will create redirect loop so avoid it.
Or if you want specific routes to be protected then attach the middleware auth to that route
Route::get('admin/profile', ['middleware' => 'auth', function () {
//
}]);
I think you are not attaching the auth middleware to your routes.
Create a middleware like this
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate
{
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
Then Group the routes and protect them like this
Route::group(['middleware' => 'auth'], function()
{
Route::get();
Route::get();
Route::get();
Route::get();
}
Offcourse, in the routes you have to specify your links etc, it will only allow the user when he is authenticated and if not then login page will be shown
To make session redirect to your login just add ->middleware('auth') in your router files as shown below I am using laravel 5.3
Ex:
Route::post('controllerName','folderName\fileName#fnNmae')->middleware('auth');
Or visit https://laravel.com/docs/5.3/authentication