Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save diaafares/355923ed80c25ef1f352b07f11cf356f to your computer and use it in GitHub Desktop.

Select an option

Save diaafares/355923ed80c25ef1f352b07f11cf356f to your computer and use it in GitHub Desktop.
Obfuscate Auto Increment IDs Laravel Middleware
<?php
namespace App\Http\Middleware;
use Closure;
use Hashids\Hashids;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;
/**
* A middleware for Laravel projects to obfuscate/deobfuscate
* the auto-increment integer id(s) being sent to Response, and
* the same id(s) coming back in Request.
* This technique assists in avoiding random snooping by bots.
*
* It recursively obfuscate/deobfuscate all the key-value pairs
* in which the key (field) name as _id as suffix. You can add more cases by
* changing the const SUFFIX defined at the beginning of the class.
*
* @note You will be needed to do: composer require hashids/hashids
*
* @author Madhur Bhaiya
*/
class ObfuscateId
{
protected const SUFFIX = ['_id'];
protected Hashids $hashids_ob;
public function __construct()
{
$this->hashids_ob = new Hashids(Config::get('app.key', 'yourdefaultsecretkey'), 16);
}
/**
* Decrypts the '*_id' keys in the Request object.
* Encrypts the '*_id' keys in the Response object
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$this->deobfuscateRequest($request);
$response = $next($request);
if ($response instanceof JsonResponse) {
$this->obfuscateJsonResponse($response);
}
return $response;
}
/**
* @param Request $request
*/
protected function deobfuscateRequest(Request &$request)
{
$obf_req = $this->obfuscateIdInArray($request->all(), false);
$request->merge($obf_req);
}
/**
* @param array $data
* @param bool $switch true to obfuscate; false to deobfuscate
* @return array
*/
protected function obfuscateIdInArray(array $data, bool $switch): array
{
array_walk_recursive(
$data,
function (&$value, $key) use ($switch) {
if ($this->checkIfKeyIsId($key)) {
$value = $this->obfuscate($value, $switch);
}
}
);
return $data;
}
/**
* @param string $key
* @return bool
*/
public function checkIfKeyIsId(string $key): bool
{
return Str::endsWith(strtolower(trim($key)), self::SUFFIX);
}
/**
* @param mixed $value
* @param bool $switch true to obfuscate; false to deobfuscate
* @return mixed
*/
protected function obfuscate($value, bool $switch)
{
// Obfuscate logic
if ($switch) {
$obf_value = $this->hashids_ob->encode($value);
return ($obf_value !== '' ? $obf_value : $value);
}
// Deobfuscate logic
$deobf_value = $this->hashids_ob->decode($value);
return (sizeof($deobf_value) === 1 ? $deobf_value[0] : $value);
}
/**
* @param JsonResponse $response
*/
protected function obfuscateJsonResponse(JsonResponse &$response)
{
$response_arr = $response->getData(true);
$response_data = $response_arr['data'] ?? [];
$deobf_resp_data = $this->obfuscateIdInArray($response_data, true);
$response_arr['data'] = $deobf_resp_data;
$response->setData($response_arr);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment