I know web middleware group is assigned to every route now. But can someone tell me how to remove if for specefic route? I tried:
class HomeController extends Controller{
public function __construct(){
$this->middleware('web',['except'=>[
'index',
]]);
}
}
And it doesn't work.
Web middleware is now applied to all routes in routes.php. This happens in the RouteServiceProvider map function.
If you have an api for example which should not use web middleware you can go with something like this
public function map(Router $router)
{
$this->mapWebRoutes($router);
$this->mapApiRoutes($router);
}
protected function mapWebRoutes(Router $router)
{
$router->group([
'namespace' => $this->namespace, 'middleware' => 'web',
], function ($router) {
require app_path('Http/routes.php');
});
}
protected function mapApiRoutes(Router $router)
{
$router->group([
'namespace' => $this->namespace, 'middleware' => 'api',
], function ($router) {
require app_path('Http/routes-api.php');
});
}
Now every route in routes.php has web middleware and everything in routes-api.php the api middleware
Related
I have this route:
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'middleware' => ['web', 'auth']], function () {;
Route::get('/', function () {
return view('backend.app');
})->middleware(['auth'])->name('dashboard');
Route::get('/news', 'News#index');
});
use App\Http\Controllers\News;
Route::get('/news', [News::class, 'index']);
Route::get('/news/{id}', [News::class, 'show']);
I need to open link /admin/news - but I have error: Target class [Admin\News] does not exist.
News class for admin:
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
class News extends Controller
{
//
public function __construct()
{
}
public function index()
{
var_dump('test');
}
}
Can you help me: in what problem in my case?
You're mixing route definitions between the 'older' Laravel 7 style and the newer Laravel 8 style. Pick one and stick to it. If you've upgraded a project from Laravel 7 to Laravel 8, consider refactoring to keep things consistent.
As you have two News controllers, you either want to use the FQN (Fully Qualified Name) of each or alias one or both of your controllers.
use App\Http\Controllers\News;
use App\Http\Controllers\Admin\News as AdminNews; // aliased
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'middleware' => ['web', 'auth']], function () {
Route::get('/', function () {
return view('backend.app');
})->middleware(['auth'])->name('dashboard');
Route::get('/news', [AdminNews::class, 'index']);
});
Route::get('/news', [News::class, 'index']);
Route::get('/news/{id}', [News::class, 'show']);
I use Laravel 5.6.33. I would like the user can have an access to the 'dashboard' page only when he/she has signed In/Up. When I use the 'guest' middleware, the user can't access the page at all and when I use the 'auth' middleware, the user always have an access to the page. What shall I do?
Route::group(['middleware' => ['web']], function (){
Route::get('/dashboard', [
'uses' => 'UserController#getDashboard',
'as' => 'dashboard',
'middleware' => 'auth'
]);
});
I have also added $this->middleware('auth'); in the getDashboard function or in the constructor of the UserController but it doesn't work. What shall I do?
In the Kernel.php the auth address is as follows:
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
If you are using Laravel 5.6 you don't need to wrap your routes with web middleware as long as you put them inside your routes\web.php file. Laravel makes this for you in the RouteServiceProvider.php.
For your purpose the auth middleware should work. Try this instead of what you have:
Route::middleware('auth')->group(function() {
Route::get('/dashboard', [
'uses' => 'UserController#getDashboard',
'as' => 'dashboard'
]);
});
you have to do nothing.
just add the following code.
Route::group(['middleware'=>'auth'],function () {
//you can create the list of the url or the resource here to block the unath users.
Route::resource('brands', 'BrandController');
Route::resource('products', 'ProductController');
});
Or use the construct function on the controller which you want to block.
public function __construct()
{
$this->middleware('auth');
}
it will block all the function on that controller like index, create, store, update, delete. only auth can use those functions.
in my web application i have admin panel and i'm trying to make access to users that they have admin role by this code:
namespace App\Http\Middleware;
use Closure;
class CheckUserAdminRole
{
public function handle($request, Closure $next)
{
if (auth()->check()) {
if (auth()->check() && !auth()->user()->hasRole('admin')) {
auth()->logout();
return redirect(route('system.messages','userIsNotAdmin'));
}
}
return $next($request);
}
}
and in my routs i have this route group:
Route::group(['namespace' => 'Dashboard', 'middleware' => ['auth:web'], 'prefix' => 'dashboard'], function () {
$this->group(['prefix' => 'administrator'], function () {
$this->get('panel', 'AdminController#index');
});
my kernel:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
...
\App\Http\Middleware\CheckUserAdminRole::class,
];
now when i add my middleware as CheckUserAdminRole to route group like with this code:
Route::group(['namespace' => 'Dashboard', 'middleware' => ['auth:web','CheckUserAdminRole'], 'prefix' => 'dashboard'], function () {
i get this error:
Class CheckUserAdminRole does not exist
this codes couldn't resolve my problem:
php artisan route:clear
php artisan cache:clear
php artisan config:clear
composer dump-autoload
Instead of registering your middleware in the $middleware array, you should register it in $routeMiddleware like so:
protected $routeMiddleware = [
...
'checkAdmin' => \App\Http\Middleware\CheckUserAdminRole::class,
];
Note: registering a middlware in the $middleware array results in it being executed for every request and therefore is not applicable on specific routes.
Then you can use it in your routes with the checkAdmin name:
Route::group(['namespace' => 'Dashboard', 'middleware' => ['auth:web','checkAdmin'], 'prefix' => 'dashboard'], function () {
Source
You can also use middleware and route group together easily like so:
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function()
{
//All the routes that belongs to the group goes here
Route::get('dashboard', function() {} );
});
Here's a simple fix without touching the Kernel file and taking advantage of the Policy. The accessAdmin is a function created inside Policy file.
Route::group(['namespace' => 'Dashboard', 'middleware' => 'can:accessAdmin, App\User', 'prefix' => 'dashboard'], function () {
$this->group(['prefix' => 'administrator'], function () {
$this->get('panel', 'AdminController#index');
});
You can try middleware with prefix and groups.
Route::middleware(['Auth'])->prefix('api/')->group(function() {
Route::group(['prefix' => 'review/'], function () {
Route::get('/', 'User\Controllers\Api\UserController#getUserReviews');
});
});
Hope its helps
I am working with the modular structure of Laravel, and I have a main routing file and 2 routing files in the two modules. How can I make sure that all my routing files(web.php) are loading perfectly?
EDIT- I tried adding data in RoutesServiceProvider file:
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
$this->mapModuleWebRoutes1();
$this->mapModuleWebRoutes2();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* #return void
*/
protected function mapWebRoutes()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/web.php');
});
}
protected function mapModuleWebRoutes1()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
], function ($router) {-
require app_path('Modules/Course_Entry/web.php');
});
}
protected function mapModuleWebRoutes2()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
], function ($router) {
require app_path('Modules/Log_in_blog_post/web.php');
});
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* #return void
*/
protected function mapApiRoutes()
{
Route::group([
'middleware' => 'api',
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}
}
But it shows error:View [includes.message-block] not found. (View: C:\xampp\htdocs\larve\app\Modules\Log_in_blog_post\views\welcome.blade.php)
But, It is present in my module.
ProjectController:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class ProjectController extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function nextpage1()
{
return view('Course_Entry::welcome');
}
public function nextpage2()
{
return view('Log_in_blog_post::welcome');
}
}
Run php artisan route:list. If there are missing routes, make sure in which of your route files should they are. Then the problem is that this file isn't being registered by Laravel.
Create or use the already existing RouteServiceProvider to map your missing file.
UPDATE:
But it shows error:View [includes.message-block] not found. (View: C:\xampp\htdocs\larve\app\Modules\Log_in_blog_post\views\welcome.blade.php)
This error isn't related with the first one, you are probably trying to #include a view in your welcome.blade.php that doesn't exist.
Can someone explain me the following behavior, when i enable my routes (login, homepage etc) like so:
Route::group(['middleware' => 'web'], function () {
....
});
A Ajax login modal is working correctly, however when i try the following (enabling middleware in the controllers) which i prefer working with:
class PagesController extends Controller
{
public function __construct()
{
$this->middleware('web');
}
...
}
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('web');
$this->middleware('guest', ['except' => 'logout']);
}
...
}
A TokenMismatchException is trown in VerifyCsrfToken.php line 67.
To my knowledge there shouldn't be a difference in those two approaches, what am i doing wrong here?
csrf token setup:
Base layout:
<meta name="csrf-token" content="{{ csrf_token() }}">
modal js:
var options = {
emulateJSON: true,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
};
I'll give You working example, take from there ideas that will help You:
app/Http/routes.php:
// all routes that start with: "/auth" are not filtered by any middleware
Route::group(['prefix' => 'auth'], function() {
Route::get('/', ['as' => 'auth', 'uses' => 'AuthController#index']);
Route::post('/', ['as' => 'auth.attempt', 'uses' => 'AuthController#attempt']);
Route::delete('/', ['uses' => 'AuthController#destroy']);
Route::any('destroy', ['as' => 'auth.destroy', 'uses' => 'AuthController#destroy']);
});
// all routes that start with: "/billing" will be handled by this group (prefix => 'billing')
// all controllers inside this route group are located in 'Billing' namespace
// all routes in this group are pre-checked by middleware 'HasAccessToBilling'
Route::group(['prefix' => 'billing', 'namespace' => 'Billing', 'middleware' => ['App\Http\Middleware\HasAccessToBilling']], function()
{
Route::any('/', ['as' => 'billing', 'uses' => 'DashboardController#index']);
Route::get('profile', ['as' => 'billing.profile', 'uses' => 'ProfileController#index']);
// TARIFFS
Route::group(['prefix' => 'tariffs'], function() {
Route::get('/', ['as' => 'billing.tariffs', 'uses' => 'TariffsController#index']); // showing page with tariffs paginated
Route::get('all', ['as' => 'billing.tariffs.all', 'uses' => 'TariffsController#all']); // listing all tariffs with json (see controller)
Route::get('create', ['as' => 'billing.tariffs.create', 'uses' => 'TariffsController#create']); // create form
Route::post('/', ['as' => 'billing.tariffs.store', 'uses' => 'TariffsController#store']); // creating
Route::get('{id}', ['as' => 'billing.tariffs.edit', 'uses' => 'TariffsController#edit']); // edit form
Route::post('{id}', ['as' => 'billing.tariffs.update', 'uses' => 'TariffsController#update']); // updating
Route::get('{id}/activate', ['as' => 'billing.tariffs.activate', 'uses' => 'TariffsController#activate']); // active = 1
Route::get('{id}/suspend', ['as' => 'billing.tariffs.suspend', 'uses' => 'TariffsController#suspend']); // active = 0
Route::get('{id}/delete', ['as' => 'billing.tariffs.delete', 'uses' => 'TariffsController#delete']); // deleted = 1
});
app/Http/Middleware/HasAccessToBilling.php:
<?php namespace App\Http\Middleware;
use App\Library\Auth;
use Closure;
use Illuminate\Http\Request;
class HasAccessToBilling
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
if (Auth::hasAccessTo('billing', $request)) {
return $next($request);
}
return redirect()->route('auth');
}
}
app/Library/Auth.php:
<?php namespace App\Library;
use \App\Models\User;
use Illuminate\Http\Request;
use Crypt;
class Auth
{
public static function recoverSession(Request $request)
{
$rememberToken = $request->cookie('remember-token', null);
if(is_null($rememberToken)) {
return null;
}
try{
$rememberToken = Crypt::decrypt($rememberToken);
$auth = json_decode($rememberToken, true);
$request->session()->set('auth', $auth);
}
catch(\Exception $ex) {}
return $request->session()->get('auth');
}
public static function hasAccessTo($realm, Request $request)
{
$auth = $request->session()->get('auth', null);
if (is_null($auth)) {
$auth = self::recoverSession($request);
}
return (isset($auth['access_to']))?
in_array($realm, $auth['access_to'])
: false;
}
}
and finally example controller:
see namespace 'Billing' must be same with folder, otherwise You'll do manual class aliasing in composer.
app/Http/Controllers/Billing/TariffsController.php:
<?php namespace App\Http\Controllers\Billing;
use Illuminate\Http\Request;
use Redirect;
use App\Http\Controllers\Controller;
use App\Models\Tariff as Model;
class TariffsController extends Controller
{
/**
* Listing records
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$records = Model::paginate();
return view('billing.tariffs.index', compact('records'));
}
/**
* Listing all tariff plans as json
* #return \Illuminate\Http\JsonResponse
*/
public function all()
{
return $this->ok(Model::all());
}
summary:
if You defined middleware in Route::group - so no need for calling middleware inside constructor. Idea of route group is to free You from repeating code when writing routes, when giving accesses using middlewares and etc.
auth controllers must not be guarded by middleware that denies public access if it's not application for intranet. so You can see that in my routes file I've not defined middleware for "/auth" prefix routes.
I don't use csrf tokens (I don't see any reason for it, many years of work I've not ever got the moment where csrf was helpful or saved my life), so I've removed it from Kernel.php.