I'm trying to use the out-of-box Authenticate middleware globally except on auth/login and auth/logout, so that I don't need to add it in every single controller. I added it to the global middleware list in Kernel (as shown below); however, it gets stuck in an infinite auth/login redirect. For any guest, I want the page to be redirected to auth/login and stay there.
class Kernel extends HttpKernel
{
protected $middleware = [
...
\App\Http\Middleware\Authenticate::class,
];
}
It's happening because when it hits auth/login the first time, the global Authenticate kicks in and redirects to auth/login again over and over.
Is it possible to use the default Authenticate middleware globally as I've described? Do I need to create a new middleware for it?
Edit: I've concluded that Thomas' approach is good enough.
You can always use a Route Groups. In your routes.php file...
// Your login/logout routes
Route::get('login', 'Auth\AuthController#getLogin');
Route::post('login', 'Auth\AuthController#postLogin');
Route::get('logout', 'Auth\AuthController#getLogout');
Route::group(['middleware' => 'auth'], function() {
// Put all other routes here and the auth middleware will be applied on them all
});
Edit: Also, you do not need to add the Authenticate middleware to the global middleware stack. Just leave it in the default $routeMiddleware.
'auth' => \App\Http\Middleware\Authenticate::class,
Related
When i want to access to a page in my application i get an exception when i'm not logged in
ErrorException in ec75fc198343b0a46e649467428bd2d5f829caf1.php line 49:
Trying to get property of non-object
Should i make a route middleware group ?
I would like when i want to access to the pages when i'm not logging that the app redirect me directly to the login form without display me this error message !
Someone know how to do that ?
Enable the auth middleware for the action that is responsible for rendering the page. There are multiple ways how you can accomplish this in Laravel. Here are a few of them:
In the routes file for a particular action
Route::get('your/page', ['middleware' => 'auth', 'uses' => 'YourPageController#index']);
or the same thing fluently
Route::get('your/page', 'YourPageController#index')->middleware('auth');
In the routes file for a group of actions/pages
Route::group(['middleware' => ['auth'], function () {
Route::get('your/page', 'YourPageController#index');
});
In the controller
class YourPageController extends Controller
{
public function __construct()
{
$this->middleware('auth'); // you can pass an array of actions/methods that should not be covered by the auth middleware in a second parameter ['except' => 'someaction']
}
}
Edit your Kernel.php and add this to the protected $routeMiddleware part at the end:
'auth' => \App\Http\Middleware\Authenticate::class,
Then in your routes you can use this 'auth' to check if the user is logged in.
For example:
Route::get('/example', 'YourController#getExample')->middleware('auth');
if you don't have a middleware or you have any trouble follow this https://laravel.com/docs/5.4/authentication
Include the Middleware in routes.
Route::get('/Demo','DemoLine#index')->middleware('auth');
I have an issue with auth:api middleware!
We have a request that is accessible for both authenticated users and non-authenticated users when I define a route like this for non-authenticated users:
Route::post('{user}/leads', 'UsersController#getContact');
It's ok everything work fine when a guest user requesting this route.
is and I can access user with $request->user();
but if pass token with bearer header and get the user with $request->user() of course it doesn't work! because we didn't use auth:api on this route, and if we do we can't access this route with guest users!
So I can't find a way that we define one route for both authenticated users that if user is authenticated we get $request->user() and none authenticated users can access that route too!
Thanks in advance.
I found a way to do that I just wrote this:
$middleware = ['api'];
if (\Request::header('Authorization'))
$middleware = array_merge(['auth:api']);
Route::group(['prefix' => 'v1', 'namespace' => 'Api', 'middleware' => $middleware], function () {
//routes here
});
In api.php route file and it works fine.
Thanks
This is because Auth uses the default web guard. You have to check the api guard manually:
$user = Auth::user() ?? Auth::guard("api")->user();
Then you don't use any auth middleware. $user will be null if the user is a guest, otherwise it should be set.
The solution I used was to create a new middleware for auth:
public function handle($request, Closure $next, ...$guards)
{
try
{
$this->authenticate($request, $guards);
}
catch(AuthenticationException $ex)
{
}
return $next($request);
}
and in at the BOTTOM of my route I did:
Route::middleware('auth_optional:api')->group(function () {
Route::get('services', [ServiceController::class,'index']);
});
This way if Auth was needed ,it would assign the correct user to request, otherwise it would proceed as guest. I did need to do a $request->user() === null to make sure the user is guest
If you want the routes are visible to only Authenticate users you can put all routes in auth middleware that is default provided by laravel you can put like this:-
enter code here
Route::group(['middleware' => ['auth']], function () {
Route::post('{user}/leads', 'UsersController#getContact');
});
And if you want to show the route both authenticate and non-authenticate user
You can simply put outside the middleware
Lik that:-
Route::match(['get', 'post'], '/cms-page','CmsController#cms');
Hope you understand
I would like to use additional routes both authenticated and non-authenticated users,
But regarding the topic I add one simple way :
On the __constructor function of the Controller add those lines :
$authorizationHeader = \request()->header('Authorization');
if(isset($authorizationHeader)) {
$this->middleware('auth:api');
}
But I don't concentrate this way as best practice, this brokes Single Responsibility Principle.
If you are using Laravel Passport then this way can be more cleaner.
In controller you can directly get user by
$user = $request->user('api');
This will get you the authenticated user and if bearer token is invalid then it will not throw 'unauthenticated' error but result in null user.
Reference: How to authenticate user without auth:api middleware in laravel 5.3?
May be this type of questions already exits but i didn't find proper solution. I am new in Laravel so sorry for this question.
I am creating a laravel application where user will login and will be access information .
My questions is how to prevent user to access direct URLs.
Put your routes under 'auth' middleware in routes.php file, that way only authenticated users will able to access.
for example like below:-
Route::group(['middleware' => ['auth']], function () {
Route::get('dashboard', [
'uses' => 'DashboardController#index',
'as' => 'dashboard.index',
]);
});
Or you can write custom middleware for user validation.
Adding to Rakesh's answer,
you can also apply the middleware to the controller for the routes you need protected via the constructor.
public function __construct()
{
$this->middleware('auth');
}
I have just set up my Laravel installation and I have been reading the documentation and it appears that it ships with a authentication system built in. Which I would like to use rather than build my own ( which I have done in the previous version)
My question is I would like to change the default routes and the structure to something like:
www.example.com/register and www.example.com/login
At the moment it uses an auth folder so www.example.com/auth/register and www.example.com/auth/login
I just think that my way is cleaner and more user friendly. I would also like to change the forgot password to www.example.com/forgot-password
I have tried various examples and even new routes etc but I keep getting a not found exception. It is just bugging me as I would like to keep what is already there but alter it slightly as they say dont fix what is not broken.
Hopefully someone can point me in the right direction.
By default the default auth routes use Route::controllers(['auth' => 'Auth\AuthController']), the Route::controller() method generates the routes based upon the functions available on the controller.
You should be able to remove this line and create your own routes for them. If you look at the Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers trait you can see the functions available. Simply map your routes to those functions available on your auth controller.
Heres a couple to get your started
Route::get('/register', ['uses' => 'Auth\AuthController#getRegister']);
Route::post('/register', ['uses' => 'Auth\AuthController#postRegister']);
Route::get('/login', ['uses' => 'Auth\AuthController#getLogin']);
Route::post('/login', ['uses' => 'Auth\AuthController#postLogin']);
You can set $loginPath property in AuthController
These are some other properties you may also need
Where user is redirected after logout
$redirectAfterLogout
The post register / login redirect path
$redirectPath
Path to the login route.
$loginPath
class AuthController extends Controller {
protected $loginPath = 'login'; //example.com/login
use AuthenticatesAndRegistersUsers;
public function __construct(Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
$this->middleware('guest', ['except' => 'getLogout']);
}
}
i am new to laravel,
i have code in my controller's __construct like
if(Auth::check())
{
return View::make('view_page');
}
return Redirect::route('login')->withInput()->with('errmessage', 'Please Login to access restricted area.');
its working fine, but what i wants is. its really annoying to put these coding in each and every controller, so i wish to put this Verify Auth and redirect to login page in one place, may be in router.php or filters.php.
I have read some posts in forum as well as in stackoverflow, and added code in filters.php like below but that's too not working.
Route::filter('auth', function() {
if (Auth::guest())
return Redirect::guest('login');
});
Please help me to resolve this issue.
Laravel 5.4
Use the built in auth middleware.
Route::group(['middleware' => ['auth']], function() {
// your routes
});
For a single route:
Route::get('profile', function () {
// Only authenticated users may enter...
})->middleware('auth');
Laravel docs
Laravel 4 (original answer)
That's already built in to laravel. See the auth filter in filters.php. Just add the before filter to your routes. Preferably use a group and wrap that around your protected routes:
Route::group(array('before' => 'auth'), function(){
// your routes
Route::get('/', 'HomeController#index');
});
Or for a single route:
Route::get('/', array('before' => 'auth', 'uses' => 'HomeController#index'));
To change the redirect URL or send messages along, simply edit the filter in filters.php to your liking.
To avoid code repetition, You can use it in middleware. If you are using the Laravel build in Auth, You can directly use the auth middleware as given,
Route::group(['middleware' => ['auth']], function() {
// define your route, route groups here
});
or, for a single route,
Route::get('profile', function () {
})->middleware('auth');
If you are building your own, custom Authentication system. You should use the middleware which will check the user is authenticated or not. To create custom middleware, run php artisan make:middleware Middelware_Name_Here and register the newly created middleware.
It's absolutely correct what other people have replied.
This solution is for Laravel 5.4
But just in case, if you have more than one middleware applying to routes, make sure 'auth' middleware comes in the end and not at the start.
Like this:
Route::prefix('/admin')->group(function () {
Route::group(['middleware' => 'CheckUser', 'middleware' => 'auth'], function(){
});
});
Route::middleware(['auth'])->group(function () {
Route::get('dashboard','BackendController#dashboard')->name('dashboard');
});
This entry in the web.php route will take the user [who is not logged in] to the login page if (s)he tries to access a 'protected' URL, "dashboard" in this case.