Created
November 23, 2020 17:00
-
-
Save martindrapeau/9ce72154a1ebe780ef79d37d306c1b80 to your computer and use it in GitHub Desktop.
Laravel Middleware to verify POST and GET requests from Canva
This file contains hidden or 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\Request; | |
/** | |
* Class VerifyCanvaRequest. | |
*/ | |
class VerifyCanvaRequest | |
{ | |
protected $key; | |
public function __construct() | |
{ | |
$secret = env('CANVA_SECRET'); | |
$this->key = base64_decode(strtr($secret, '-_', '+/')); | |
} | |
public function handle(Request $request, Closure $next) | |
{ | |
if ($request->isMethod('post')) $this->verifyPostRequest($request); | |
if ($request->isMethod('get')) { | |
if (app()->environment('local') && $request->exists('bypass')) { | |
// Debug in dev simply pass bypass in query string | |
return $next($request); | |
} | |
$this->verifyGetRequest($request); | |
} | |
return $next($request); | |
} | |
public function getCanvaPath(Request $request) | |
{ | |
// Change these to match your endpoints | |
$paths = [ | |
'api/canva/configuration' => '/configuration', | |
'api/canva/publish/resources/find' => '/publish/resources/find', | |
'api/canva/publish/resources/get' => '/publish/resources/get', | |
'api/canva/publish/resources/upload' => '/publish/resources/upload', | |
]; | |
$path = $request->path(); | |
foreach ($paths as $pattern => $canva) { | |
if (strpos($path, $pattern) !== false) return $canva; | |
} | |
abort(404); | |
} | |
public function verifyPostRequest(Request $request) | |
{ | |
$version = 'v1'; | |
$timestamp = $request->header('X-Canva-Timestamp'); | |
$path = $this->getCanvaPath($request); | |
$body = $request->getContent(); | |
$message = "{$version}:{$timestamp}:{$path}:{$body}"; | |
$signatures = $request->header('X-Canva-Signatures'); | |
$signature = hash_hmac('sha256', $message, $this->key, false); | |
if (strpos($signatures, $signature) === false) abort(401); | |
if (abs(now()->timestamp - $timestamp) > 300) abort(401); | |
} | |
public function verifyGetRequest(Request $request) | |
{ | |
$version = 'v1'; | |
$timestamp = $request['time']; | |
$user = $request['user']; | |
$brand = $request['brand']; | |
$extensions = $request['extensions']; | |
$state = $request['state']; | |
$message = "{$version}:{$timestamp}:{$user}:{$brand}:{$extensions}:{$state}"; | |
$signatures = $request['signatures']; | |
$signature = hash_hmac('sha256', $message, $this->key, false); | |
if (strpos($signatures, $signature) === false) abort(401); | |
if (abs(now()->timestamp - $timestamp) > 300) abort(401); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this Martin!