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

Neel picture Neel · Sep 15, 2015 · Viewed 10.2k times · Source

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

Answer

Javi Stolz picture Javi Stolz · Sep 15, 2015

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