This is more of a design question i think
I have a simple booking system
There’s three stages and at the end the booing is confirmed and paid for
I have found while testing that i can revisit any stage of the booking process using the address bar
Urls like booking/your-details/39
That means i can alter the booking after it is completed
So my question is how to prevent that. I’ve been looking through the routing docs and it looks like that might solve it to some extent but I’m not sure it will stop someone who is determined to create mayhem.
Without a login and a session i cant quite grasp how to make this work and i’d very much appreciate it if someone out there could point me in the right direction.
Ok so here’s the basics of what seems to be a common method.
You need to create a guest user and you need to log that user on when it is created.
I added role id’s to the user table to identify different types of user.
Then I created a component. Two functions, one to create a user entity and one that takes a user entity and creates the new user record. I did it that way so i could return true or false from the create user function and get the new user id from the passed entity.
The create user function generates a randomised value for username and password - I used mt_rand
Then i used Auth->setUser to log the newly created user on and that created a session.
And that’s it.
I don’t know if it’s a good way to do it but it’s the only way I’ve found that suits what I’m doing.
I would welcome any comments on how I’ve done this though because it has been guesswork at times.
Normally, it should be enough to simply create a session (and maybe a cookie, if the form is complex and you don’t want it to time out too quickly) with a unique hash.
So for instance, once a visitor enters the first step of the process, the unique hash should be generated for them. At the same time this hash should be saved to a DB table (i.e. booking_sessions) along with the creation time and the booking id.
Then in the following booking steps the hash from the session/cookie should be compared to the DB entry.
If it is found and is not out of date, the user should be allowed to edit the corresponding booking entry. Otherwise, a message should be shown that their session has expired and they need to fill out the form again starting from the first page.
After the booking form has been completely submitted, the booking_session entry should be deleted (or allowed to become outdated).
But since no user was created, there will be no way for visitors to edit their booking details after that (but that seems to be the intended design, if I understood you correctly).
Naturally, you could also permanently allow the editing of the booking entries for special users like admins in case things need to be corrected.
Btw, creating a “guest” account seems like it should work as well, but it’s probably overkill.
Hi and thanks for the response
I was just wondering. Is the session id a unique hash?
I’m especially interested in the idea of checking a value in the database against a value from the user’s session when they try to access their record. That’s something that i did not consider.
The guest user account is associated with the booking record though so i could be checking the credentials with every access. The way you describe sounds simpler though.
I’m not all that good with sessions at the minute as i’m still learning so i was wondering what checking the credentials guards against. Is it possible for a guest user to interfere with another guest user’s record if this check is not done?
Security is something I’m worried about as it is probably my weakest area.
Well, what I described doesn’t require guest user accounts. It seems wasteful to use the Cake Auth functionality in this case, as you don’t really need things such as a username and password.
It simpler to manually use the session to only store what you actually need to get this functionality, in this case a unique hash (you can use the uuid() method of the text utility for that).
Of course, if you use guest user accounts, you won’t need a hash anymore - you should go with either the one or the other method.
Using session variables is fairly easy in cakephp. You can create one like this:
$bookingToken = $this->request->session()->write('booking_token', Text::uuid());
And then access it somewhere else like this:
It’s useful to understand that something like $this->Auth->user(‘id’) is only a placeholder for $this->request->session()->read(‘Auth.User.id’).