I'm trying to implement a "favorites" feature to my site and I was wondering on how to go about storing this data. What I'd like to do if possible is have the user favorite things and store it in the DB - that way I could use the data to personalize search results.
I'm also trying to have it so there is a smooth transition between favorites in a non logged in state to a logged in one (allow the user to save favorites anonymously but if logs in transfer/ask to transfer those to his account)
How would I be able to store this data for long periods of time? I'm currently using DB encrypted sessions and I was thinking of extending the session time or setting it to not expire. That would probably lead me to some security issues no?
I'd appreciate the help,
Cheers.
Well, if i understand, what you want is that a registered user can set "something" as a favorite, since this is a M:N relationship (strictly from a database point of view), i would recommend a table storing these relationships, i.e. Supposing you have a user and a topic table, the SQL would like similar to this:
create table favorite(user_id integer not null references user, topic_id integer not null references topic);
At least this is what most DB books will tell you to do. If you don't have a user table (i suppose you have one for that "something" you want to mark as favorite), you could just store the id you assign to the user whenever s/he logs into the system. Hope to have been of help.
Create actual users out of your anonymous sessions. Persist them in the database without login credentials and associate favorites or whatever else you store with their user ID. If they sign up before they clear their cookies, you just add their login/profile into to the existing user ID and all the favorites they've created are already in the right spot. One system for both logged in and logged out users, not two.
Related
I've heard that creating a session and assigning a session ID to each user is the way to go for a case like this. However, I'm still a little unsure- if the user closes their browser or clears their cookies then the session is deleted from what I understand. And even then, sessions are temporary so the session will be deleted regardless. Doesn't that mean that whenever the session ends- the users data is wiped? And therefore if they wanted to get their data back they'd have to create a brand new account and the program would have to interpret their new data all over again only to be deleted again later? I apologize for my lack of understanding- I'm fairly new to this. How would I make it so that my website retains the data unique to each user permanently? And am I misunderstanding the concept of sessions in PHP?This image will show the design structure of my two tables. I've attempted to reference one to the other to no avail unfortunately. The green link between them represents the reference of the idUsers column in the "users" table (user account information), and the userIDs as the foreign key, a column in the "user_classes" table.
I figure that this should be possible, as it is a requirement asked by my supervisor. There are a few types of accounts, one of them is a 'company' account which should allow anyone in the company who has these credentials to log in at the same time.
Now my question is, how do I store temporary data like:
(this is fictive)
shopping carts, keeping track of wizards,...
I suppose that I'll have to store this in the database?
What would be my best option. Link it to the unique session id?
Yes, you can store sessions in your database if you like. A nice way to do it, is by creating a sessions like table that stores states. Therefore, if you have a cart, you can have a cart table that represents what products the cart has and replay that after a user logs back in.
Session information isn't based on your account-system but on the system of the visitor (cookie). Unless you want all information to be shared across all users logged in on the company account (which I doubt) you shouldn't have to store any of the information in the database.
To store the data you can simply keep using session (as I suppose you already do for the 'normal' account.
I have a form for editing users. The user ID is passed to the client (in a hidden field) so that I know which user to update when the form is posted back to the server. My question is, how can I guard against users changing the ID in the DOM, thereby updating a record to which they should not have access?
The only ways I can think of are:
Save the user ID in the session. (Painful).
Run a salted hash on the user ID (and perhaps other form elements) and include it also as a hidden form element. (Not particularly secure?)
Are there other approaches?
Thanks!
EDIT: Hey, some great responses coming in. Note that the logged in user and the user being edited may be two different users, e.g. a Manager is editing a Staff record.
The best way to do this is to just check after submission if the user has the right to edit that user.
Don't pollute the session with this data, because it can get messy, for example when a user opens the same page multiple times.
It depends somewhat on the conditions under which the user is allowed to edit it.
At the heart of it, it comes down to:
Authenticate the user
Check if the user is authorized to make that change
Authenticating the user is usually a case of "Do the username and password match?" or "Is there an active session with a logged in user associated with it?"
Authorization depends on your business logic. It might be "Is the logged in user the same as the user being edited?" or "Does the user being edited have a manger field containing the id of the logged in user?" and so on.
In the first case, storing the user id in the session shouldn't be painful. In the second case, you just do a database lookup as one of the first things you do in the script.
Why are you relying on a hidden field for knowing which record to update? If the user is logged in you should already have the user_id of him with you on the session.
So you can just find which record to update by finding which user is logged in.
As mentioned, the fastest and painless way to sort this would be to stick the USER_ID in the session, period.
Comments saying that you "pollute" session with that information are plainly uneducated, ignore them.
The other thing I noticed in comments is the "check if the user has the rights to edit the entry" which implies there's some sort of hierarchical system in place, which seems not to be true.
Alternative to session storage would be, as you assumed already, obfuscating the USER_ID value in the hidden field somehow. You could either encrypt it, or instead of integer ID - you could use GUIDs but that has implications of its own, tho it makes it incredibly hard for someone to "guess" the correct GUID to mess around with the records.
I just found out that stackoverflow has a link to logout every logged computers.
So..I thought about how to implement same functionality in PHP. I came up with using session_set_save_haldner to control write() method. In write() method, I can make a session file start with user's username. For example, a user john might have session files john_kdkajdkak, and john_29039dla. When John clicks "Logout Everywhere", I can write a code that finds filenames start with "john" then remove them to clear sessions.
are there any other better solutions? How did you implement it if you already made it work?
Use a database to persist session data.
Using session_set_save_handler you can roll your own database storage backend for user sessions - a sessions that has a user_id foreign key, related to the users table. A "logout everywhere" button would trigger simple DELETE FROM sessions WHERE user_id = 1234 and invalidate every session for the user.
You can also easily add in additional columns to the session table - to store the IP address of the session, for instance, so users can see where other sessions are logged in from.
Use a database for flexibility and performance.
If you have multiple sites on the same domain, like StackExchange does, then you can do this with PHP.
As Billy already pointed out, the better practice would be to use database storage for this.
In your situation I'd think about using a CAS or similar solution.
But it all boils down to how many different sites you will have with the same account.
A feature that is currently missing from one of my web apps is that a single user can only be logged in on one machine at a time. That is, if the users logs in elsewhere, his previous session will be logged off.
This is due to my current users table having the columns:
user: id, username, hash, salt... cursession
When each user logs in, the session ID is put into the "cursession" field and on each page-load, is checked against the database. As a result, only one "session" can be active at a time.
Is the current table structure and method secure and standard? This system was pretty much improvised, and I have no professional experience.
What would be a way to allow multiple simultaneous logins? I'm simply thinking of adding a "sessions" table with more userid-cursession relations, but what's the standard method for doing this?
I propose that you put the current logged in userid in the user's session (as a session variable), and drop the cursession field from the table altogether. You don't need to reinvent session handling since PHP already has it built-in.
That way the user can be logged in at multiple computers at once. Session variables are safe too, since they're not manipulated by the browser. The only thing kept in the browser is a session id which identifies the current session, all other data is stored on the server-side. The only thing that will happen if the user changes his browser cookies is that he will be logged out (start an empty session), so he can't force himself to log in as someone else.