Apply Auth Middleware to All Laravel Routes - laravel

What is the correct way to authenticate all routes except login and register when I apply auth middleware in all controllers? Is there a way to apply auth middleware in one place and exclude login, register routes?

You can group all your authenticated routes like following, laravel provides a default middleware for auth and guest users
Route::group(['middleware' => ['auth']], function () {
Route::get('home', 'HomeController#index');
Route::post('save-user', 'UserController#saveUser');
Route::put('edit-user', 'UserController#editUser');
});
The above route names are just made up, please follow a proper naming convention for your routes and controllers. Also read about middlewares over here and about routing over here

you can apply middlewares in the routes.php file, what you need to do is to put all your routes on a group, and add the middleware 'auth' ( except the Auth::routes() which are already configured), for example :
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second Middleware
});
Route::get('user/profile', function () {
// Uses first & second Middleware
});
});
more information can be found in the docs: https://laravel.com/docs/5.7/routing#route-group-middleware

You can add middleware to your whole web.php route file by adding the middleware to your routes mapping in RouteServiceProvider.
Go to app/Providers/RouteServiceProvider.php and in mapWebRoutes(), change middleware('web') to middleware(['web', 'auth']):
protected function mapWebRoutes()
{
Route::middleware(['web', 'auth'])
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
This is (not?) totally unrelated but here's an example of a clean way to handle a lot of route files instead of throwing all your routes into a single web.php file:
Create a new method mapAdminRoutes():
protected function mapAdminRoutes()
{
Route::middleware(['web', 'auth:admin'])
->namespace('App\Http\Controllers\Admin')
->name('admin.')
->group(base_path('routes/admin.php'));
}
Map it:
public function map()
{
$this->mapWebRoutes();
$this->mapAdminRoutes(); // <-- add this
...
}
Create an admin.php file in your routes folder, then create your routes for Admin:
<?php
use Illuminate\Support\Facades\Route;
// This route's name will be 'admin.dashboard'
Route::get('dashboard', 'DashboardController#dashboard')->name('dashboard');
// This route's name will be 'admin.example'
Route::get('example', 'ExampleController#example')->name('example');
...
Now you can configure everything in 1 place, like prefix, name, middleware and namespace.
Check php artisan route:list to see the results :)

Related

Laravel auth middleware returns route not defined

I'm new to laravel and I'm trying to secure some routes wherein only authenticated users can access it.
I've followed instructions on grouping my web routes on an auth middle ware, so I did my routes/web.php it like this...
Route::group(['middleware' => 'auth'], function () {
Route::get('/feed', [FeedController::class, 'feed']);
Route::get('/profile', [ProfileController::class, 'profile']);
});
Route::get('/', [LandingController::class, 'landing']);
and my App/Http/Middleware/Authenticate.php like this....
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('/');
}
}
but when I access these guarded routes unauthenticated, it gives me error saying
Symfony\Component\Routing\Exception\RouteNotFoundException
Route [/] not defined.
Can someone point me on the right way here?

Laravel Route not defined for registercontroller

I'm new to Laravel and I inherited a project. I saw that there was a app/Http/Controller/Auth/RegisterController.php, but going to the websites /register gave me a 404 error. So I added this line to routes/web.php
Route::get('/register', 'RegistrationController#create')->name('register.create');
Route::post('/register', 'RegistrationController#store');
And now I can go to the url /register and sign up a new user without any issues.
I went into resources/views/auth/login.blade.php and added the line
Don't have an account? Sign up
But this gave me an error Route [register.create] not defined. View(.. path to login.blade.php
What did I do wrong?
Answer
The reason why you it's returning a 404 is because when you manually register the registration routes and you do it before the Auth::routes which registers one with the same key that overwrites yours. Hence why it's working if you move them after the Auth::routes.
What you could do is disable the register routes from the Auth facade:
Route::get('/register', 'RegistrationController#create')->name('register.create');
Route::post('/register', 'RegistrationController#store');
Auth::routes(['register' => false]);
If you plan on using Laravel's default registration system, you simply have to remove your manually registered routes and create the respective views and you can access the route with route('register');.
You can also check the other available routes generated by the Auth facade with php artisan route:list.
Note
Also, you do not need to group them in the web middleware when adding routes in routes/web.php because they are automatically in the middleware by the RouteServiceProvider.
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
I solved the problem. I made a guess changed this:
Route::group(['middleware' => ['web']], function () {
... other code ...
Route::get('/register', 'RegistrationController#create')->name('register.create');
Route::post('/register', 'RegistrationController#store');
Auth::routes();
... other code ...
});
To this
Route::group(['middleware' => ['web']], function () {
... other code ...
Auth::routes();
... other code ...
});
Route::get('/register', 'RegistrationController#create')->name('register.create');
Route::post('/register', 'RegistrationController#store');
And it worked. NOt sure if this is the right way to do it though

Auth::user() is null in new route

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();

Laravel routes not working with subfolder

Using Laravel 5 migrated from 4.2 now laravel 5 is installed in subfolder "abc" do i have to write abc/warehouse for every route ? previously it was /warehouse. i want to use all existing routes like /warehouse inside subdirectory abc.
i am on localhost xampp with port 81. http://localhost:81/warehouse
any one here with quick solution
You use prefix when defining routes:
Route::prefix('abc')->group(...)
Route Prefixes
Route::prefix('abc')->group(function () {
Route::get('warehouse', function () {
// Matches The "/abc/warehouse" URL
});
});
Ideally you should do it in the RouteServiceProvider
Route::middleware('web')
->prefix('abc')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
This way everything in the routes file is prefixed and you dont need the extra group wrapping.
Here's the example from the 5.0 docs:
Route::group(['prefix' => 'admin'], function() {
Route::get('users', function() {
// Matches The "/admin/users" URL
});
});
what you can do is add a line in RouteServiceProvider in mapWebRoutes function like this
public function mapWebRoutes()
{
//default
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
//subfolder
Route::middleware('web')
->prefix('abc')
->namespace($this->namespace)
->group(base_path('routes/abc.php'));
}
then create a file inside routes/abc.php and copy paste all your routes inside it
Route prefix https://laravel.com/docs/5.6/routing#route-group-prefixes
For laravel 5.0 you have to wrap inside Route::group
Route::group(['prefix' => 'abc', 'namespace' => 'Auth'], function(){
//define all your routes here
Route::post('login', 'AuthController#login');
});
Namespace: Here i have define Auth in namespace that means my all controllers like AuthController files should be inside app/Http/Controllers/Auth folders.
Laravel route 5.0 https://laravel.com/docs/5.0/routing#route-group-prefixes
For laravel 5.0 namespace structure check this https://laravel.com/docs/5.0/structure

Redirect to Login if user not logged in Laravel

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.

Resources