cloudcreativity / laravel-json-api

JSON API (jsonapi.org) package for Laravel applications.
http://laravel-json-api.readthedocs.io/en/latest/
Apache License 2.0
780 stars 109 forks source link

Convert hashed IDs in requests #380

Closed jackcoup closed 5 years ago

jackcoup commented 5 years ago

Hi,

Thanks for all your hard work. Great package!

I have a question around obscuring ids of records in requests and responses. I want to obscure all ids for example 123 would become x4n2KEe9

What I've done so far:

However I'm unable to modify the content of the request when I PATCH to /users/{hashedId} it throws a resourceIdNotSupported exception.

Please could you advise on the best way to approach this?

lindyhopchris commented 5 years ago

Hi! Glad you're finding the package useful.

This will be great to get this working as I'd imagine this is a really common use case. Out of interest, what are you using to hash the ids? I might be interested in adding support for this into the package so people could opt in to it.

In terms of hashing the id... the schema is responsible for serializing the model's id in the getId() method, so you can either do it there or your approach of overriding the $model->getRouteKey() method if you want to use the hashed id in other places.

The adapter is responsible for all JSON API database queries, so that's definitely the place to override it to unhash the id. I'll need to push a change so that there is one method for you to overload on your adapter to make that easy.

lindyhopchris commented 5 years ago

Ok, I've just pushed an update that means you can overload the databaseId() method on your adapters. I'd suggest adding a method to your model trait, e.g. something like getKeyFromRouteKey($routeKey), and then in your adapter you can do:

protected function databaseId(string $resourceId)
{
    return $this->model->getKeyFromRouteKey($resourceId);
}

The reason I've put this in the adapter is there's loads of places throughout the implementation that resource ids are used... e.g. when an resource id is used to modify a relationship. So by putting the logic in a single method in the adapter, then it is consistently handled throughout the API.

To give it a go:

$ composer require cloudcreativity/laravel-json-api:1.x-dev

And let me know how you get on!

jackcoup commented 5 years ago

Fantastic! Thanks so much for the quick response and commit.

I'm using the Hashids library - https://hashids.org/

That sounds like the right implementation, it makes sense and is simple to be in the adapter. Great I'll try it out and let you know if anything comes up.

lindyhopchris commented 5 years ago

Released as 1.3.0 - feel free to reopen if you find any problems.