Ajax Middleware - laravel

I seem to remember in Laravel 4 there was an ajax filter, this would only allow requests via ajax.
Is there any similar middleware for Laravel 5.
I have a route which gets data from my database via ajax, I want to protect this route so no user can go to it and see a json string of data.

You can use a middleware to do that.
php artisan make:middleware AllowOnlyAjaxRequests
app/Http/Middleware/AllowOnlyAjaxRequests.php
<?php
namespace App\Http\Middleware;
use Closure;
class AllowOnlyAjaxRequests
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(!$request->ajax()) {
// Handle the non-ajax request
return response('', 405);
}
return $next($request);
}
}
Add 'ajax' => \App\Http\Middleware\AllowOnlyAjaxRequests::class, to your routeMiddleware array in app/Http/Kernel.php.
Then you can use ajax middleware on your routes.

Related

Laravel 8: GET params can't be accessed in Middleware's Request's inputs

I have defined this route in the web.php route file:
Route::get('/middleware_test_user_project_change/{pro_id}/{projet_id}', function ($pro_id, $projet_id) {
return 'test';
})->middleware('user.project.change');
I have defined this handle function in my middleware (which I've added into the kernel with the following entry: 'user.project.change' => \App\Http\Middleware\CheckUserProposition::class):
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use App\Models\User;
class CheckUserProposition
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$projet_id = $request->input('projet_id');
$pro_id = $request->input('pro_id');
return $next($request);
}
}
However, both $projet_id and $pro_id return NULL when I access the following URL: https://XYZ/middleware_test_user_project_change/1/1
As I've correctly set up the middleware and the routes parameters (which are, finally, GET variables), why can't I use them in my middleware as request inputs?
Route parameters are not part of the 'inputs'. They are a separate thing; this is why you don't see them when you get all the inputs with $request->all().
If you want a route parameter you should probably explicitly ask for it:
$request->route('projet_id');
$request->route()->parameter('projet_id');

Assigning middleware inside a Middleware handle function in Laravel

I want to know If it is possible to assign a middleware or execute a middleware in handle function of another middleware
<?php
namespace App\Http\Middleware;
use Closure;
class AuthTypeMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if($request->header('auth_type') === "api") {
// execute the auth:api middleware here
}
else {
// execute the auth middleware here
}
}
}
I know we can achieve this by creating different route groups with prefix but still I wanted to know if their any possibility of getting this work

Return every request as plain json Laravel using Middleware

I have a route in my web.php that returns a view:
Route::get('/', function () {
return view('welcome');
});
welcome is default Laravel view welcome.blade.php.
I have Middleware called AlwaysReturnJson and it contains:
<?php
namespace App\Http\Middleware;
use Closure;
class AlwaysReturnJson
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
I set up this middleware in Kernel.php as global middleware:
protected $middleware = [
\App\Http\Middleware\AlwaysReturnJson::class
];
What I expect is to get plain text/json of welcome file in my browser when I navigate to given route but I always get it as html and it render page properly. I checked it, it applies middleware on every request so that is not a problem. Why is this happening and shouldn't it convert that view to a plain text? Am I doing something wrong?
If you want to set a header for your response you can do this:
namespace App\Http\Middleware;
use Closure;
class AlwaysReturnJson
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
If you want to force return valid json content use this middleware instead:
namespace App\Http\Middleware;
use Closure;
class AlwaysReturnJson
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
return response()->json($response->getContent());
}
}
See Laravel docs about after middleware for more info.
You can alternatively return json response on your controller without any middleware needed:
Route::get('/', function () {
return response()->json(
view('welcome')->render()
);
});
You may want to use laravel After middleware (the middleware would perform its task after the request is handled by the application) and then set the content-type of response.
<?php
namespace App\Http\Middleware;
use Closure;
class AfterAlwaysReturnJson
{
public function handle($request, Closure $next)
{
$response = $next($request);
return $response->header('Content-Type', 'application/json');
}
}

how to redirect with https for particular page only in laravel

i want to redirect particular page only to https, rest of page will remain in normal http.
i want to do this for payment page only.after successful payment site will run with normal http.
so please help me for do this.
i already try this one.
Route::resource('paynow', ['uses' => 'Account\PaymentController', 'https' => true]);
but this will not work for me.
I would go about it by creating a custom middleware in app\http\middleware to intercept the request before it hits those routes.
<?php
namespace App\Http\Middleware;
use Closure;
class SecurePayment
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (!$request->secure()) {
return redirect()->secure($request->getRequestUri());
}
return $next($request);
}
}
Then add it to app/http/kernel.php in the route middleware group
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
.....
'secure-payment' => \App\Http\Middleware\SecurePayment::class,
];
and finally wrap your route in the group
Route::group(['middleware' => ['secure-payment']], function() {
Route::resource('paynow', ['uses' => 'Account\PaymentController']);
}):

How to prevent Laravel Routes from being accessed directly (i.e. non-ajax requests)

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 () {
// ...
});

Resources