laravel middleware. Most efficient way - php

At the moment I'm working with laravel 5 project, which contains ~100 post and get routes. I'm trying to add middlewares here but logics behind this project is really complicated. Middlewares will do really important role here. Before I was using groups, for example:
Route::group(['middleware' => 'auth'], function(){
//routes
});
But everything became really messy since I had to create groups in group, for example:
Route::group(['middleware' => 'auth'], function(){
Route::group(['middleware' => 'status'], function(){
//routes
});
});
At the moment I have 20 controllers, so each of them contains about 5 routes. Could you suggest me more efficent way to use middlewares in big projects. What way do you use? Thanks in advance!

It all depends on which middlewares you need to have applied to different routes.
If you have groups of routes that share the same middleware set, then the easiest way to do is what you do in the first example:
Route::group(['middleware' => 'auth'], function(){
//routes
});
If you have some roots that share common middlewares, but each of them might have some specific middleware applied, then nesting routes and route groups withing existing group like you do in the second example is a way to go:
Route::group(['middleware' => 'auth'], function(){
Route::group(['middleware' => 'status'], function(){
//routes
});
Route::get('/uri/', ['middleware' => 'some_other_middleware']);
});
Finally, when different routes have different middleware sets and you are not able to group them in any way, you'll need to apply a set of middlewares to each of them:
Route::get('/uri1/', ['middleware' => 'some_middleware']);
Route::get('/uri2/', ['middleware' => 'some_other_middleware']);
Long story short - if you have complex rules on what middleware to apply to what routes, then setting it up in the routes.php file will reflect the complexity.
It might be also true that some of the things you do in the middleware should belong to some other layer in the application and moving the logic there could simplify routes.php, but it all depends on what routes and middlewares you have.

Related

Mixing laravel route groups

I need to have routes group with prefix and middlewares all in one but not sure how to do so? In laravel documents there is no such complex sample.
Here is what I want:
Route::group({Prefix}, {middleware}, function(){...});
I am aware that I can add middlewares at the end of my route groups like:
Route::group({Prefix}, function(){...})->middleware('xxxx');
But I like the shape of first sample (all in one at the top of group).
So anyone can help to figure that out?
Try something like this,
Route::group(['middleware' => 'cors', 'prefix' => '/v1/test'], function () {
Route::post('/', 'Admin\testController#create');
Route::post('/list', 'Admin\testController#list');
Route::post('/view', 'Admin\testController#view');
Route::post('/update', 'Admin\testController#update');
});
Try below code.
if you use multiple middleware.
Route::group(['prefix' => 'admin', 'middleware' => ['auth','admin']], function() {
});

Laravel - Routes with "sub" views

I am just getting started with Laravel and find the route setup a little confusing. I am trying to create a few pages, that ultimately should have the struture:
domain.com/onboarding
domain.com/onboarding/skip
domain.com/onboarding/skip/anothersubview
etc.
Right now I have:
// Registered and Activated User Routes
Route::group(['middleware' => ['auth', 'activated', 'activity']], function () {
Route::get('/onboarding', 'UserController#Onboarding')->name('onboarding');
});
Would the solution here (and best practice) be to just add another route inside my Route::group, like:
Route::view('/onboarding/skip', 'onboarding.skip');
Is this the correct way of doing things?
use prefix :
Route::group(['prefix' => 'onboarding','middleware' => ['auth', 'activated', 'activity']], function () {
Route::get('/', 'UserController#Onboarding')->name('onboarding');
Route::get('/skip', 'UserController#OnboardingSkip')->name('onboarding_skip');
Route::get('/skip/anothersubview', 'UserController#OnboardingSkipSubview')->name('onboarding_skipsubview');
});
read more here : https://laravel.com/docs/5.6/routing
The structure I used in a few projects in the past looks like this:
Route::group(['prefix' => 'onboarding'], function(){
Route::group(['prefix' => 'something'], function(){
Route::get('/', function(){}); //onboarding/something
Route::group(['prefix' => 'somethingelse'], function(){
Route::get('/', function(){}); //onboarding/something/somethingelse
Route::get('/{id}', function(){}); //onboarding/something/somethingelse/15
});
});
});
nesting groups can help you make the easier extendable router because when you realize you need to add some URL in the middle of long structure it would be easier to do it with this concept
You have a web.php file in your routes folder, there you need to add:
Route::get('/subpage', 'controllername#function-name-you-want-to-call');
Hope this helps, if it doesn't let me know
/e: to clarify:
the first part
Route::group(['middleware' => ['auth', 'activated', 'activity']], function () {
is the authentication. Depending on who you want to access this page, you might not need it

Which middleware to use if I want the route to be accessible by guests, authenticated users and everyone else?

At first I decided to organize my routes like I have in the code given below. However, I quickly realized that I couldn't access the routes in the group that uses middleware guest as soon as I log in. Does that mean that routes which I want to be accessible by anyone no matter whether they're logged in or not should not be in any middleware group?
<?php
Route::group(['middleware' => ['web']], function(){
Route::group(['middleware' => ['guest']], function(){
Route::get('/', 'PagesController#index')->name('home');
Route::get('/image/{id}', 'PagesController#specificImage')->name('specificImage');
Route::get('/contact', 'PagesController#contact')->name('contact');
Route::get('/tags', 'PagesController#tags')->name('tags');
Route::get('/tags/{tagName}', 'PagesController#specificTag')->name('specificTag');
Route::get('/albums', 'PagesController#albums')->name('albums');
Route::get('/albums/{albumId}/{albumName}', 'PagesController#specificAlbum')->name('specificAlbum');
Route::post('/signup', 'UsersController#signUp')->name('signup');
Route::post('/signin', 'UsersController#signIn')->name('signin');
Route::post('/sendmail', 'UsersController#sendMail')->name('sendmail');
});
Route::group(['middleware' => ['auth']], function(){
Route::get('/upload', 'PagesController#upload')->name('upload');
Route::get('/logout', 'UsersController#logOut')->name('logout');
Route::get('/imageDelete/{imageId}', 'ImagesController#deleteImage')->name('deleteImage');
Route::get('/deleteTag/{tagId}', 'TagsController#deleteTag')->name('deleteTag');
Route::post('/imageUpload', 'ImagesController#uploadImage')->name('imageUpload');
Route::post('/albumUpload', 'AlbumsController#uploadAlbum')->name('albumUpload');
Route::post('/createTag', 'TagsController#createTag')->name('createTag');
});
});
Remove auth middleware from the route group
Correct! Get rid of the guest middleware, you don't need it.
Just Do not use any middleware.

Laravel5 assign Middleware to route patterns

Assume i have 1 application and two external packages.
Package 1 defines routes like api/v1/package1/foo
Package 2 defines routes like api/v1/package2/bar
In my main application i want to apply some Middleware for each api/v1/* route.
How to do this?
Use Route Groups to accomplish this. You can set prefix or domain groups, namespace groups, and middleware groups this way.
For example:
Route::group(['prefix' => 'api/v1'], function(){
Route::group(['prefix'=>'package1', 'middleware' => 'package1.middleware']), function({
Route::get('foo', 'FooController#foo');
});
Route::group(['prefix' => 'package2', 'middleware' => 'package2.middleware']), function({
Route::get('bar', 'BarController#bar');
});
});

Laravel Routing - Separate some routes

I have a route defined as:
Route::resource('item', 'ItemController');
What I want to do is put some of these routes, particularly edit and delete inside a group.
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
}
This doesn't work, though. Do I have to define each route one by one then? Or is there a better solution to this?
EDIT:
I'm sorry, but it seems I did not ask the question properly. So let me make some clarifications here.
I have a basic auth user which can create and view items. What I don't want it to do is edit and delete.
I then also have a role user which do everything auth can do AND edit and delete items.
So basically, regular authorized users can have SOME access to items while role users have COMPLETE access.
The current code seems to give role users ONLY edit and delete functionalities and no view or create.
To make it even more clearer, here's what my actual route looks like:
Route::group(['middleware' => ['auth']], function()
{
Route::resource('items', 'SitesController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
});
});
Maybe I'm going about this the wrong way?
The code above will work, you just named the action incorrectly. You should have used destroy instead of delete. Try the following code:
Route::resource('item', 'ItemController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'destroy']]);
});
You can run php artisan route:list to verify. You should see role middleware enabled in 2 of your routes.

Categories