The problem in a nutshell
I am looking for a way to remove VerifyCsrfToken
from a global middleware pipeline from within a package without user modification App\Http\Middleware\VerifyCsrfToken
. Is it possible?
Usage example
I am developing a package that will facilitate the safe addition of push-to-deploy functions to any Laravel project. I start with github. Github uses webhooks to notify third-party applications of events such as clicks or releases. In other words, I would register a URL, such as http://myapp.com/deploy on Github, and Github would send a request POST
to this URL with useful information containing information about the event when this occurs, and I could use this event to start a new deployment. Obviously, I don’t want to start the deployment on time if some random (or possibly malicious) agent other than the Github service gets to this URL. This way, Github has a process to protect your web hosts.. This includes registering a private key with Github, which they will use to send a special, secure hashed header along with the request, which you can use to verify it.
My approach to security includes:
Random Unique URL / Route and Secret Key
First, I automatically generate two random unique strings that are stored in a file .env
and are used to create a private key route in my application. In the file, .env
it looks like this:
AUTODEPLOY_SECRET=BHBfCiC0bjIDCAGH2I54JACwKNrC2dqn
AUTODEPLOY_ROUTE=UG2Yu8QzHY6KbxvLNxcRs0HVy9lQnKsx
config
for this package creates two keys auto-deploy.secret
and auto-deploy.route
which I can get when registering a route so that it never gets published in any repo:
Route::post(config('auto-deploy.route'),'MyController@index');
Then I can go to Github and register my website as follows:
![Github Web Host Registration Screen](https://fooobar.com//img/fdab54f78bb090a7597794b5c1da6b60.png)
, URL- , , , .
Webhook
Laravel, webhook. , , , Laracasts. ServiceProvider
:
public function boot(Illuminate\Contracts\Http\Kernel $kernel)
{
$kernel->prependMiddleware(Middleware\VerifyWebhookRequest::class);
include __DIR__.'/routes.php';
}
Route
:
Route::post(
config('auto-deploy.route'), [
'as' => 'autodeployroute',
'uses' => 'MyPackage\AutoDeploy\Controllers\DeployController@index',
]
);
handle()
, :
public function handle($request, Closure $next)
{
if ($request->path() === config('auto-deploy.route')) {
if ($request->secure()) {
if () {
return $next($request);
} else {
abort(403);
}
} else {
abort(403);
}
}
return $next($request);
}
continue on to controller
.
, , POST
, session()
CSRF
, VerifyCsrfToken
TokenMismatchException
. , - VerifyCsrfToken
. , .
# 1: VerifyCsrfToken
URL- $except
App\Http\Middleware\VerifyCsrfToken
,
protected $except = [
'UG2Yu8QzHY6KbxvLNxcRs0HVy9lQnKsx',
];
, , , , , . , :
protected $except = [
config('auto-deploy.route'),
];
PHP . :
protected $except = [
'autodeployroute',
];
. URL. , , - :
protected $except = [];
public function __construct(\Illuminate\Contracts\Encryption\Encrypter $encrypter)
{
parent::__construct($encrypter);
$this->except[] = config('auto-deploy.route');
}
Laravel. , , , , -, . , , , , , , Laravel, .
# 2: catch
TokenMismatchException
, , , , , ..:
public function handle($request, Closure $next)
{
if ($request->secure() && $request->path() === config('auto-deploy.route')) {
if ($request->secure()) {
if () {
try {
$response = $next($request);
} catch (TokenMismatchException $e) {
return $response;
}
} else {
abort(403);
}
} else {
abort(403);
}
}
return $next($request);
}
, . wabbit, , try/catch
! , $response
- undefined catch
. $next($request)
catch
, TokenMismatchException
.
# 3:
, Controller
handle()
. , . , - , , Laravel , . , , .
# 4: Pipeline
, Pipeline Laravel. Laravel . , , , Pipeline
, , CSRF . , , , - . , , !
# 5: WithoutMiddleware
, , , , , . , , , . , .
? , push-to-deploy, , ? , , 5 , - 5 10 . , . , , , , , .
, , , . ? , , .
№1: Laravel , !
, , . "" " ---", , , ., , , " " , . , .
№ 2: ,
, - , . , ; , . , , : " !" ?
, :
, .
P.S. - , , , , , .