71 lines
2.0 KiB
PHP
71 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace Slack\Http\Middleware;
|
|
|
|
use Carbon\Carbon;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
use Slack\Base;
|
|
|
|
class CheckSignature
|
|
{
|
|
private const LOGKEY = 'MCS';
|
|
|
|
/**
|
|
* Validate a slack request
|
|
* by the slack signing secret (not the token)
|
|
*
|
|
* @param Request $request
|
|
* @param Closure $next
|
|
* @return mixed
|
|
*/
|
|
public function handle(Request $request,Closure $next)
|
|
{
|
|
// Make sure we are not an installation call
|
|
if (! in_array($request->path(),config('slack.bypass_routes'))) {
|
|
// get the remote sign
|
|
$remote_signature = $request->header('X-Slack-Signature');
|
|
Log::info(sprintf('%s:Incoming request - check slack SIGNATURE [%s]',static::LOGKEY,$remote_signature),['m'=>__METHOD__]);
|
|
|
|
// Load the secret, you also can load it from env(YOUR_OWN_SLACK_SECRET)
|
|
$secret = config('slack.signing_secret');
|
|
|
|
$body = $request->getContent();
|
|
|
|
// Compare timestamp with the local time, according to the slack official documents
|
|
// the gap should under 5 minutes
|
|
// @codeCoverageIgnoreStart
|
|
if (! $timestamp = $request->header('X-Slack-Request-Timestamp')) {
|
|
Log::alert(sprintf('%s:No slack timestamp - aborting...',static::LOGKEY),['m'=>__METHOD__]);
|
|
|
|
return response('',444);
|
|
}
|
|
|
|
if (($x=Carbon::now()->diffInMinutes(Carbon::createFromTimestamp($timestamp))) > 5) {
|
|
Log::alert(sprintf('%s:Invalid slack timestamp [%d]',static::LOGKEY,$x),['m'=>__METHOD__]);
|
|
|
|
return response('',444);
|
|
}
|
|
// @codeCoverageIgnoreEnd
|
|
|
|
// generate the string base
|
|
$sig_basestring = sprintf('%s:%s:%s',Base::signature_version,$timestamp,$body);
|
|
|
|
// generate the local sign
|
|
$hash = hash_hmac('sha256',$sig_basestring,$secret);
|
|
$local_signature = sprintf('%s=%s',Base::signature_version,$hash);
|
|
|
|
// check two signs, if not match, throw an error
|
|
if ($remote_signature !== $local_signature) {
|
|
Log::alert(sprintf('%s:Invalid slack signature [%s]',static::LOGKEY,$remote_signature),['m'=>__METHOD__]);
|
|
|
|
return response('',444);
|
|
}
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
}
|