i did a migration from Laravel 4.2 to 5.0, and reading another questions, i created a new Middleware on my app\http\middleware but, i don't know how implement this to my RouteServiceProvider.php
This is my BeforeMiddleware:
<?php namespace App\Http\Middleware;
use Closure;
class BeforeMiddleware {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
And on my RouteServiceProvider i got this
App::before(function($request)
{
//I think here need to be my code...
});
You need to register your middleware in the app/Http/Kernel.php file.
Here you will find 3 options:
protected $middleware = [..] <-- run on EVERY request
protected $middlewareGroups = ['web'=>...] <-- run on all web routes
protected $routeMiddleware = ['auth'...] <-- run on routes when defined
I had to deal with this same situation some time ago for a CRM, and the ideal approach is to migrate what you had within App::before() in Laravel 4.2 to a service provider in Laravel 5.0.
At first you can just use the boot() method located in the AppServiceProvider, in a way that you can test the waters.
From there you can opt to have a dedicated service provider just to hold this part, such as AppBeforeServiceProvider.
You have mentioned a migration to middleware, but that is actually for filters coming from Laravel 4.2.
Related
Is there a way to make a route APP_DEBUG exclusive in Laravel 8?
I can set routes in the PreventRequestsDuringMaintenance middleware exception list.
But that is only for when maintenance mode is on.
I know I can simply do an abort(403) on a Route if Debug mode is on but I'm using Laravel Web Console library which communicates with it's own route when executing commands. So I need to strictly block any requests to that route when in Debug mode.
I want to block certain routes when not in Debug mode. Does Laravel come with such option or do I need a third party library?
As James suggested it, I tinkered with middlewares and registered a global middleware to abort 403 if any uri matches one from a blacklist.
protected $middleware = [
...
// allows blocking some requests when debug mode is off
\App\Http\Middleware\PreventRequestsDuringProduction::class,
];
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
class PreventRequestsDuringProduction
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$blacklist = [
'console',
'laravelwebconsole/execute'
];
$uri = Route::getRoutes()->match($request)->uri;
if(\in_array($uri, $blacklist) && !env('APP_DEBUG')) {
abort(403);
}
return $next($request);
}
}
I am new to laravel and trying to make a panel for food delivery
I have used Laravel default Registration and Login for User Category--Restaurant
and then after user login , the user can Add restaurant details using route (/add_details)
once the user has added restaurant details the user should not be able to go to that route (/add_details)
this will depend on a column in restaurant table (is_verified)
how do i check that
I was thinking of using a Laravel middleware
but then i was stuck how laravel middleware $request variable works
how can i get column value in middleware and verify it
or if any other simple but effective solution
as
i will be using it in sidebar.blade.php as well
so that i can hide the menu
I made a middleware and added it to kernel.php and is using it in routes
Its working fine
but i want to ask is this the right way i have done it
Route::get('/manage_cuisines', 'RestaurantCuisineController#create')->name('manage-cuisines')->middleware('restaurant_verified');
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
use \App\User;
use \App\Restaurant;
class CheckRestaurantVerification
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$restaurant = Restaurant::find(User::find(Auth::id())->restaurant_id);
if($restaurant->is_verified == 0)
{
return redirect('home');
}
return $next($request);
}
}
I would like a group of routes to be accessible with either the standard auth:api middleware, or via the CheckClientCredentials middleware.
I can't see how this would be possible as there is no ability to set middleware as only requiring one of the listed middleware.
Is there a Passport middleware which allows any type of API authentication that I don't know about?
Or is there a clean way of creating a custom middleware which tests for either of the middleware?
I took Joshuas advice about the similar answer here and created a new middleware encompassing the two auth middleware.
Working Middleware class for anyone else hitting this issue below. This will try the Auth guard middleware first and if this fails to authenticate the request it will then try to authenticate using the Client Credentials Passport middleware.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Auth\Middleware\Authenticate as AuthGuardMiddleware;
use Laravel\Passport\Http\Middleware\CheckClientCredentials as ClientCredMiddleware;
class AuthenticateWithApiOrClientCreds
{
/**
* Authenticate a request with either Authenticate OR CheckClientCredentials Middleware
*
* #param $request
* #param Closure $next
* #param mixed ...$scopes
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function handle($request, Closure $next, ...$scopes)
{
$auth_guard_middleware = app()->make(AuthGuardMiddleware::class);
try {
$response = $auth_guard_middleware->handle($request, $next, 'api');
} catch (AuthenticationException $e) {
$client_cred_middleware = app()->make(ClientCredMiddleware::class);
$response = $client_cred_middleware->handle($request, $next, ...$scopes);
}
return $response;
}
}
Laravel doesn't provide the OR middleware. Although there are several workarounds like it was previously asked here.
If you are looking for the way to change the api.php default middleware (default to auth:api), you can see it in directory: app\Providers\RouteServiceProvider.php with function name: mapApiRoutes().
I ended up storing all the routes that need authentication in a separate route file called api-authenticated.php. In RouteServiceProvider.php I'm applying the web and api middleware groups for those routes conditionally based on the presence of the Authorization header. When the Authorization header is set, you know the user is an API client.
In Providers/RouteServiceProvider.php:
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* #return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->apiNamespace)
->name('api.')
->group(__DIR__ . '/../../routes/api.php');
}
/**
* Define the authenticated "api" routes for the application.
*
* These routes are typically stateless, but are also used in
* a stateful context as the first-party uses cookies for
* authenticaton
*
* #return void
*/
public function mapAuthenticatedApiRoutes()
{
$stateless = request()->hasHeader('Authorization');
Route::prefix('api')
->middleware($stateless ? ['api', 'auth:api'] : ['web', 'auth'])
->namespace($this->apiNamespace)
->name('api.')
->group(__DIR__ . '/../../routes/api-authenticated.php');
}
I'm quite new to Laravel and have been stumped on a problem for 2 days - I'd be grateful for some guidance.
I'm using the default out-of-the-box User authentication system with Laravel 5.3. A new user is created automatically behind the scenes by an existing Admin user - I will in time hide the user registration page. I have also successfully set up middleware to check if a user is newly registered (by looking for a null 'last_logged_in_date' that I've added to the migration).
All I want to happen is for a new registered user to be redirected to the password reset screen that ships with Laravel (again, in time I will create a dedicated page). I would like this to happen within the middleware file. So far, my middleware looks like this:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
class CheckIfNewUser
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
}
}
I'm not sure what code to enter at the location indicated by the comments above. I've tried sendResetLinkEmail($request); etc and have imported what I though were the correct classes but I always end up with a Call to undefined function App\Http\Middleware\sendResetLinkEmail() message irregardless of what I 'use' at the top of my class.
Where am I going wrong? Thanks!
Well that happens because you have not defined your sendResetLinkEmail($request) function yet. You can do it like this, or you can create a new class with that and then call the class.
Call the trait SendsPasswordResetEmails and then access it with $this since traits are not classes and you cannot access their members directly.
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class CheckIfNewUser
{
use SendsPasswordResetEmails;
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
//EDIT
//return $this->SendsPasswordResetEmails->sendResetLinkEmail($request);
return $this->sendResetLinkEmail($request);
}
}
In my project, I am using Laravel purely as a backend api and all frontend is handled by Angular javascript. At the moment, the Laravel routes can be accessed directly and it will cough out all the data in Json that shows in the browser. I want to put a restriction on it so Laravel only responds to Ajax requests and nothing else.
I read this post here which has a solution for Laravel 4 that is by adding a restriction in filter.php. But as of Laravel 5.1, filters are no longer used and I believe Middleware can be used to do the same. However, I am not sure how to go ahead changing the Laravel 4 solution in that SO answer from filter to Middleware.
Can someone share your ideas on how to prevent Laravel 5.1 routes from being accessed directly please?
Laravel 4 solution using filter.php:
In filter.php declare this filter:
Route::filter('isAJAX', function()
{
if (!Request::AJAX()) return Redirect::to('/')->with(array('route' => Request::path()));
});
Then put all your routes that you only want accessible via AJAX into a group. In your routes.php:
Route::group(array('before' => 'isAJAX'), function()
{
Route::get('contacts/{name}', ContactController#index); // Or however you declared your route
... // More routes
});
Create the middleware file app/Http/Middleware/OnlyAjax.php with this content:
<?php
namespace App\Http\Middleware;
class OnlyAjax
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, \Closure $next)
{
if ( ! $request->ajax())
return response('Forbidden.', 403);
return $next($request);
}
}
Then register your middleware in the file app/Http/Kernel.php
<?php namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* #var array
*/
protected $middleware = [
//... your original code
];
/**
* The application's route middleware.
*
* #var array
*/
protected $routeMiddleware = [
//... your original code
'ajax' => \App\Http\Middleware\OnlyAjax::class,
];
}
And finally attach the middleware to any route or group of routes you want to make only accessible via AJAX. i.e:
/// File: routes/web.php
// Single route
Route::any('foo', 'FooController#doSomething')->middleware('ajax');
// Route group
Route::middleware(['ajax'])->group(function () {
// ...
});