How can we do to apply this methods to models before sending the response to the browser and in the other direction from browser to backend to Unhash it. Do you have any ideas ? It will make my day
You may also consider using an Ecto custom type. Using a custom type would allow to pass the hashId directly in your Ecto queries and the conversion happens “automagically” as Ecto accesses the database.
I do this to convert big integers to and from strings for JSON APIs that are consumed by JavaScript as JavaScript only supports 53 bit integers and will mangle anything larger. Sending them as strings solves that issue and with the custom type the query result can be passed directly to Poison etc.
JavaScript does not support integers at all. Ecmascript itself does only talk about numbers in general and how the are represented is up to the implementation. You might have IS engines that do not even use integers at all but treat everything floating point.
I usually hate it when people respond to questions like this, but here I go:
Why do you want to do this? If your system is designed securely, ID obfuscation shouldn’t add any security benefits. Knowing an ID should never be enough to give you unauthorized access to data. This is especially true if you’re using an auto-incrementing ID scheme.
It’s not a security matters - we’re building a Software as a Service - and we do not want that a customer see this route for example: url/users/4 -> this means you are the fourth users of the service - this is not very comforting…
ahah - good one but this is not what i call a SOLUTION, it’s very easy for someone to check that the service is new - for example a creation of blog post : you will create one and get this url/posts/43728433 - you create another one day later you have /url/posts/43728436 - YEAHH 3 posts have been created in one day and you call yourself as the new Medium
Set the serial field to increment by a random prime number (instead of by 1) of the set of {7,13,23,53} or so just to make things a bit more random? ^.^
Another solution to this is to use Universally unique identifier’s. We make extensive use of UUIDv4 and it works well for us. Ecto/Postgres has good support for generating them automatically and if you want to generate one manually you can just call:
I definitely agree with the others if this is your concern I would just use a UUID as your primary key. It’s very easy with recent updates to Ecto and it works great.
Hello. I just had an idea. In “Programming phenix” the authors talk about the Phoenix.Param protocol as a way to convert structs to urls and back with an ecto type. I didn’t have a chance to use that yet but I think it might be what you need.
UUID is def the way to go for that, but I would say that if you don’t want to change all your PKs to be :binary_id then you could just add another column into the tables that you want, and have that as a UUID so you can use that to lookup on.
So rather than looking up on /users/1 with
select * from users where id = 1
you could do /users/2a8b5954-fd9d-4ec8-8ee5-ec0d2b2ea8e4
select * from users where uuid = '2a8b5954-fd9d-4ec8-8ee5-ec0d2b2ea8e4'
and keep your PKs as ints internally, and only expose a UUID on things that need it.
Another approach may be to look at using a “snowflake” primary key. Although its purpose is to creating a sortable, globally-unique ID for all bits of data in your system it does have a side effect of making the sequence obfuscated without requiring virtual fields or additional hashing. And since you’re building a SaaS it also prepares you for horizontal scaling.