I need somehow to make my routes non-guessable.
Actually a user finish the operation cycle (order status is finish) by making a get request via a QR-CODE reading.
But is pretty easy to 'guess' the route since the id is the same in the whole order life-cycle. The users can see the id in URL when the status is acepted (before finish).
So I was thinking to add a kind of random token to the url so they can't guess the route...
My routes are like this atm:
resources :orders, only: %i(create show index destroy edit update) do
resources :reviews, only: %i(create new show index)
resources :payments, only: %i(new create)
member do
post 'accept'
end
member do
get 'read_qrcode'
end
end
Which generates this pattern to read_qrcode route:
/orders/:id/read_qrcode
So I was thinking to add any kind of token, maybe MD5 Hash, timestamp or whatever after read_qrcode and get a url like this:
/orders/:id/read_qrcode/1a79a4d60de6718e8e5b326e338ae533
How can I achieve this result, or maybe another solution to this?
Make the token the md5 of the concatenation of the ID and a secret.
So, let’s say the secret is “-no-guessing!”.
With an ID of 1, then md5(“1-no-guessing!) is 9493F2E821BA8B1FC791A048BBCD9A19
And with ID 2, the token would be AD17E6D3551BF0C0A2B0D5A029AEFBB2
Those are legit MD5 hashes of the strings in the example, you should be able to verify that.
But I would need to know the secret to be able to generate this. Your app knows the secret, but your user does not.
When your orders#read_qrcode action is processed, pass the token as a get param (no need for it to be a path param). Then, have the controller generate the md5 of the concatenation of ID and the secret, comparing it with the token passed as a param
What I’ve described above is essentially an HMAC, where the “message” is the ID of the order. See https://en.m.wikipedia.org/wiki/HMAC for more on HMACs