Today I needed to protect a group of routes from everything except my testing environment. I need to run PHPUnit tests that depend on certain routes, but I don’t want those routes to be available anywhere else. I’ll share in this blog post what I did to get what I need.
Assumptions in this tutorial:
You already have Laravel 5 installed on your computer and you are running the app in “testing” mode (e.g. PHPUnit testing)
Introduction
In Laravel, Middleware filters requests that are coming into our application. One of the pre-made Middleware in Laravel 5.2 is Authenticate
, which looks like this:
Inside the handle() method, it checks if the request is using AJAX -or- is asking for JSON, and if either condition returns TRUE, it blocks access and returns ‘Unauthorized’ as response. Otherwise, client is redirected to the ‘login’ route, which should happen when client is requesting via web browser.
What I did to make my grouped routes available only in testing environment (in my case, when running PHPUnit) was create a new Middlewave. I’ll show you how.
Create a new file under Http/Middleware
and name it TestingEnvOnly.php
In the handle method, we check if app environment is set to testing, and if so, we allow the request to access the requested route. Otherwise, the request should fail and repond with ‘Unavailable’.
Now, let’s register this Middleware to Http/Middleware
. Add the following to the $routeMiddleware
array:
It’s time to add a testing-only route:
If you use PHPUnit like I do, you can test our new Middleware by creating this test method:
I’m only using var_dump so that we can easily see the printed string response which should say “This should be visible only for testing environment” when you run PHPUnit.
Now, in your web browser, visit the route your set for /api/v1/testing_env_only
. It should say ‘Unauthorized’.
Here’s how the files I edited in Laravel look like now:
I’m using Laravel 5.2 and these are codes I uploaded at Gist
<?php | |
// App/Http/Middleware/TestingEnvOnly.php | |
namespace App\Http\Middleware; | |
use \App\Http\Controllers\API\ApiLogsController; | |
use Closure; | |
use \Log; | |
/** | |
* Check if phpunit is the one running the app | |
*/ | |
class TestingEnvOnly | |
{ | |
/** | |
* Handle an incoming request. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @param \Closure $next | |
* @return mixed | |
*/ | |
public function handle($request, Closure $next) | |
{ | |
if(env('APP_ENV') == "testing"){ | |
return $next($request); | |
} else { | |
return response('Unavailable.', 401); | |
} | |
} | |
} |
<?php | |
// Http/Kernel.php | |
namespace App\Http; | |
use Illuminate\Foundation\Http\Kernel as HttpKernel; | |
class Kernel extends HttpKernel | |
{ | |
/** | |
* The application's global HTTP middleware stack. | |
* | |
* These middleware are run during every request to your application. | |
* | |
* @var array | |
*/ | |
protected $middleware = [ | |
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class/*, | |
\App\Http\Middleware\LogAfterRequest::class*/ | |
]; | |
/** | |
* The application's route middleware groups. | |
* | |
* @var array | |
*/ | |
protected $middlewareGroups = [ | |
'web' => [ | |
\App\Http\Middleware\EncryptCookies::class, | |
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, | |
\Illuminate\Session\Middleware\StartSession::class, | |
\Illuminate\View\Middleware\ShareErrorsFromSession::class, | |
\App\Http\Middleware\VerifyCsrfToken::class, | |
], | |
'api' => [ | |
'throttle:60,1', | |
], | |
]; | |
/** | |
* The application's route middleware. | |
* | |
* These middleware may be assigned to groups or used individually. | |
* | |
* @var array | |
*/ | |
protected $routeMiddleware = [ | |
'auth' => \App\Http\Middleware\Authenticate::class, | |
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, | |
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class, | |
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, | |
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, | |
'testing' => \App\Http\Middleware\TestingEnvOnly::class | |
]; | |
} |
<?php | |
// Http/routes.php | |
Route::group(['middleware' => ['testing']], function(){ | |
Route::get("testing_env_only", function(){ | |
echo "This should be visible only for testing environment"; | |
}); | |
}); |