Forked from madhurbhaiya/gist:f84dec82b7f36007559a9e0568422338
Created
September 8, 2020 18:41
-
-
Save diaafares/355923ed80c25ef1f352b07f11cf356f to your computer and use it in GitHub Desktop.
Obfuscate Auto Increment IDs Laravel Middleware
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 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