Created
April 24, 2017 21:55
-
-
Save paulredmond/14523d3bd8062f9ce48cdd1340b3f171 to your computer and use it in GitHub Desktop.
Laravel Middleware to Validate a signed Mailgun webhook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Middleware; | |
use Closure; | |
use Illuminate\Http\Response; | |
/** | |
* Validate Mailgun Webhooks | |
* @see https://documentation.mailgun.com/user_manual.html#securing-webhooks | |
*/ | |
class ValidateMailgunWebhook | |
{ | |
/** | |
* Handle an incoming request. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @param \Closure $next | |
* @return mixed | |
*/ | |
public function handle($request, Closure $next) | |
{ | |
if (!$request->isMethod('post')) { | |
abort(Response::HTTP_FORBIDDEN, 'Only POST requests are allowed.'); | |
} | |
if ($this->verify($request)) { | |
return $next($request); | |
} | |
abort(Response::HTTP_FORBIDDEN); | |
} | |
/** | |
* Build the signature from POST data | |
* | |
* @see https://documentation.mailgun.com/user_manual.html#securing-webhooks | |
* @param $request The request object | |
* @return string | |
*/ | |
private function buildSignature($request) | |
{ | |
return hash_hmac( | |
'sha256', | |
sprintf('%s%s', $request->input('timestamp'), $request->input('token')), | |
config('services.mailgun.secret') | |
); | |
} | |
private function verify($request) | |
{ | |
// Check if the timestamp is fresh | |
if (abs(time() - $request->input('timestamp')) > 15) { | |
return false; | |
} | |
return $this->buildSignature($request) === $request->input('signature'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello Paul, I was using this middleware for validating the "legacy webhooks" but this seems not to work with the new webhooks.
It needs a few tweaks, for example in line 45 $request->input('timestamp') needs to change to $request->input('signature.timestamp') and $request->input('token') to $request->input('signature.token').
The same in line 53 and 57, need to add signature.
Thank you.