Conditionally include CSRF token verification in laravel 5 routes

While developing web application in laravel 5 you find that it always require csrf token for every request. I mean when ever you create form in your view you always have to add token as hidden input field. Also you have to mentioned this csrf token while you are making ajax request.
For example

	//In FORM
	<form method="post" action={{some_action"}}>
	<input type="hidden" name="_token" value="{{ csrf_token() }}">
	.....
		Other form stuff
	....
	</form>

And in ajax

	
	//In Ajax request
	
	$.ajax({
        url: {{ route('route_name')}},
		type: "post",
    	dataType: 'json',
		data: { param1: value, param2:  value, _token: {{ csrf_token() }} },

		success:function(data){
			//success callback
		}
	});

You can notice that in both the cases you have to include csrf token while making request. This happens because laravel app by default add VerifyCsrfToken middleware on each routes by adding following line to app/Http/Kernel.php in $middleware array in Kernel class.

	'App\Http\Middleware\VerifyCsrfToken',

If you do not wish to add this middleware on every routes you can remove this line and add it to routeMiddleware middleware array in same Kernel class. So finally your $routeMiddleware array become as metnioned below.

	protected $routeMiddleware = [
		'auth' => 'L5Test\Http\Middleware\Authenticate',
		'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
		'guest' => 'L5Test\Http\Middleware\RedirectIfAuthenticated',
		'verifyCsrf' => 'App\Http\Middleware\VerifyCsrfToken',
	];

And you can add verifyCsrf middleware as per your route need as mention below.

	Route::post('postUser',['middleware' => 'verifyCsrf' , 'uses' => 'UserController@postCreateUser']);

or in controller constructor.

	
	$this->middleware('verifyCsrd',['only' => 'postCreateUser']);

If you do not like above approach and strictly want that you need csrf protection on every routes which contains form request but would like to exclude some specific routes. Hove ever in some cases you completely not needed this middleware. For example consider you are developing an android app and API for that app is developed in laravel. So Android app is written in Java and Laravel api is written in PHP. So you have to call one API to get csrf token before making any API call. So to avoid this situation. You can ignore some routes in verifycsrdtoken middleware and pass request to next to controller. To achive this open VerifyCsrfToken.php middleware and declare $excludedRoutes array inside class.

	/**
	     * Routes we want to exclude.
	     *
	     * @var array
	     */
	    protected $routes = [
        	    'useres/create',
        	    'useres/update',
		    'settings'
	    ];

and inside handle method write below code before return next($request)


		if ( $this->excludedRoutes($request) )
        {
            return $next($request);
        }

Alos you have to write exlidedRoutes method inside verifycsrftoken class

	 /**
     * This will return a bool value based on route checking.
     * @param  Request $request
     * @return boolean
     */
    protected function excludedRoutes($request)
    {
        foreach($this->routes as $route)
		{
            if ($request->is($route))
                return true;
		}
        return false;
    }

so finally your verifycsrftoken.php file will conatin below code.


	class VerifyCsrfToken extends BaseVerifier {
	
	/**
     * Routes we want to exclude.
     *
     * @var array
     */
    protected $routes = [
            'useres/create',
            'useres/update',
             'settings'
    ];

	/**
	 * Handle an incoming request.
	 *
	 * @param  \Illuminate\Http\Request  $request
	 * @param  \Closure  $next
	 * @return mixed
	 */
	public function handle($request, Closure $next)
	{
		if ( $this->excludedRoutes($request) )
        {
            return $next($request);
        }
		return parent::handle($request, $next);
	}
	 /**
     * This will return a bool value based on route checking.
     * @param  Request $request
     * @return boolean
     */
    protected function excludedRoutes($request)
    {
        foreach($this->routes as $route)
		{
            if ($request->is($route))
                return true;
		}
        return false;
    }

}

Please not that i am not including any namespace and use statement as they are different in your case.

You can see that inside handle method we are checking that if requested routes is from our excluded routes list using exludedRoutes method and pass request to next which is probably your controller action and laravel will not apply check csrf token for that route.

Advertisements

5 thoughts on “Conditionally include CSRF token verification in laravel 5 routes

  1. Thanks for your article. What I want to say is that when looking for a good on-line electronics store, look for a web site with total information on critical indicators such as the personal privacy statement, safety measures details, any payment guidelines, along with terms in addition to policies. Always take time to look at help and FAQ areas to get a far better idea of the way the shop operates, what they are able to do for you, and in what way you can make use of the features.

    Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s