I have login system in my site and users have to pay for using my site. As they have to pay, I am afraid that one user may share his username and password with another users. So I have to set my login system in such way that no user can use more than one browser at a time. But they can change the browser from time to time (not at the same time but different periods of a day). How can I implement that by php? Any idea?
You could generate a token/hash from their session ID whenever they log in. Add this token as a cookie value and then store it in the database. If the user is logged in and their cookie value doesn't match the value stored in the database, then they've probably logged in somewhere else.
Use helper javascript preloader to collect non-personal browser information and generate a hash from login time/account/IP/browser info.
Check on server side that no more than one hashes are active per user account at a time and force logout on former ones if that happens. Use another client-side javascript to periodically ping server and check hash uniqueness and seamlessly re-login legitimate users for "dynamic IP" use case.
Thus if user shares his account with another user they will keep constantly "kicking" each other out of site until annoyed enough to pay for second account.
Detect his IP and on every change make him add the computer (like Steam does it) and set a flag with last access date. On each action he makes update the field (like an online system) if no activity present in 10 minutes from other 'computers' he is accessing only 1 , you can`t prevent this because people can be ignorant, even if you make them enter sensible data to make him more sceptical in giving his credential is futile...
The only way which comes to my mind is you can keep a flag(a table column) in the database once the user logged in. So if he tries to login again, you will check if the flag is set. If it is set, then you can give error.. And remember to reset that flag once the user logged out..
Try checking the ip, or use 2 factor authentication.
(for example require the user to click a link in his e-mails to login)
Related
I haven’t written the code yet, as I am new to using cookies and trying to wrap my mind around the concept of coding cookies. I’m going to be combing the use of cookies and session data for my login system.
Because there is a time limit set in my cookies, I would think this would need to be updated periodically to keep the cookie active.
My plan:
User Logs in
Cookies are set for user ID, a random token, and a random serial key, and IP address (should I include the IP?)
Cookie data is stored in a database for when cookie is retrieved to validate the information.
I’m setting cookies to be valid for 1 month.
How often should cookie data be updated and when would you recommend updating it?
Should I update every time the server checks to see if user is logged
in or should it be sparatic? Should it only be updated if a session
isn’t found and it checks for cookie validity?
I’m new to this, so any info would be helpful before I start writing this code.
First of all, I would suggest a framework for developing anything in php and I wouldn't try to re-invent the wheel with things like cookies, when frameworks have code to deal with them already - be that Laravel, Codeigniter (in any order).
Setting the cookie for a month should be optional - i.e. give your user the choice whether this is a one time login, otherwise their account may be at risk, say they're using a public computer.
The most simple form, is to update a database whenever a logged in user refreshes a page, based on the session, not the cookie. The cookie is editable client-side, therefore should not be relied on for this updating mechanism. It can be trusted more so for the "remember me" feature, because you can assign specific user ID's to specific tokens/cookie data, meaning that you can then check to see an exact match, if not that means that somebody has tampered with the cookie.
I wouldn't recommend doing both - updating database and updating cookie. Set the cookie once, on login, then just play with a session database.
Not sure I would trust the IP, bearing in mind your IP can now be spoofed and changed via external software, on top of a simple router restart which may assign new IP's on re-connection. It could be an option, but it cannot be the only basis of authentication.
example from comments, clarification:
Say I am a user with ID 1, who has a mobile phone, a tablet and a PC.
Cookies are default valid for 14 days from date and time of login and are only inserted once, and are never updated thereafter.
I have enabled the "remember me" feature on all 3 of my devices as I logged in today -
mobile phone - 17.04.2018 at 12:00
tablet - 17.04.2018 at 12.20
PC - 17.04.2018 at 12.30
We travel to the future, and we the date is now the 28.04.2018.
11 days have passed.
I enable the feature on a new device, my partners phone for example.
The system should automatically remove the "stored" login from my mobile phone, even though 14 days haven't passed (because 3 is the maximum sessions that can be remembered per account).
The example I have provided only makes sense if you want to create a "secure" website which keeps control of not only active cookies but also of previous ones. Obviously, to be more secure I would't even give 3 remember me sessions, but only allow one or two.
If a limit is not what I was after, I would just give the user a settings page where they can deal with other active sessions on their account and give them the choice whether to remotely log those devices out or not.
I'm creating a site where users will need to register to participate. I'm on a deadline, and I don't really want to write an entire user registration / login system, so I'm thinking I'll let the Twitter API handle it. I've registered an application with Twitter and I've got the proper PHP code to allow users to sign in and allow access to my application. The thing is, I don't want users to have to log in every time they visit the site, I'd like to implement a "stay signed in" option, I'm just having trouble figuring out how to do it.
I could simply store the oauth_token and oauth_token_secret in a cookie and simply read the cookie every time someone visits the site. The existence (or absence) of those cookie values will determine whether or not the person is authorized with twitter. Of course, this is a simple approach, and bad things could happen if users decided to mess with the cookie.
Another approach would be to store only the oauth_token in the cookie, and save both the oauth_token and oauth_token_secret in my database. When the user visits, I check for the cookie value and if it's present, I check the database for a matching value and fetch the secret token, but things could still go wrong if the user ever gets ahold of someone else's oauth_token key.
The final option would be to store both the token and token_secret in the database and generate a unique random value, perhaps do some arbitrary operations on it to further obscure it, maybe md5() it, and store THAT value in the cookie and also in the database.
Of course, I really know nothing about this kind of thing, which is why I opted to not write my own user system. Basically I just don't want the user to have to sign in every time (or even to have to click the "Sign in with Twitter" link every time). If they're already signed in and have already approved my application to access their account, I want them to be able to visit the site and have it remember them. What would be the best way to do this?
The "stay logged in" part could be handled by you. You get the user to login via twitter the first time and then set a cookie. In future you check to see if a cookie is set and if so use that to auto-login the user and failing that offer twitter for login.
You don't need to force twitter to do the stay-logged in part.
I have developed a web application in PHP for a client. The client is now renting out access to the system to another company on a per user basis.
Is there a way to prevent the secondary company to use a single login and give it to 20 people to use at the same time? I know one can get the IP address of the client machine that is being logged in from, but this is obviously not very reliable method. The answer probably lies in a combination of cookies and tracking things in a database, but my brain gets a bit stuck thinking on how to implement a strategy here.
Create a unique session ID when a user logs in and store that in the DB. Add something to the session authentication code (run on all page visits) that checks that the user's session ID is equal to the one in the DB and if not, log them out. Then your web app will be accessible by only one user at a time.
To be completely honest though, can't you raise this issue with your client?
No way to tell if the login is shared among 20 people. You can restrict access by blocking simultaneous usage thru session cookies.
Most of all, protect yourself with a published Terms and Conditions document. Violation of which - revokes any standing agreement/contract. And sue them if you can provide evidence (logs) that they violated it.
Make sure you bind one user to one session. In that way you can generate a warning screen if somebody uses the same login with another session. You can then let the user choose to close the other session.
In that way you can make sure two users are not using the system at the same time. It's a bit like a software program you have installed on a computer: multiple users can use it, but only one at a time. This is probably fine.
If you don't want that, you should try to bind the login more firmly to the user: make sure he logs in with a personal e-mail address, and he gets notifications (if applicable) via e-mail. Also let the user set personal configurations. In that way you create extra value for users to have their own account.
If you have a login you have authentication, and you write any user id in session, make sure that only one session with this id created, if the session already exists throw error message.
The only problem you will have in case and user did not logout properly, instead of it pressing x button on browser then he will not be able to login till session s not expired.
How should I design a login system so that each username can only be logged on in one place at a time? I want to keep users from giving their username to someone else to login so they can avoid paying for each user.
If a user is already logged in and tries to log in on another machine should I block the 2nd login (which could be a problem if the user was logged on at work and then tried to get on at home)? Or should I allow the 2nd login and end the 1st login? Or does anyone have a better suggestion?
Some Instant Messengers (that can work only with one logged in endpoint) have a nice way of sorting out such conflicts. They show a message like
You are already logged on from <COMPUTERNAME>
(in case of a web app, that would be <IP/Browser>)
and give you a choice between
either leaving that logon alive (and not log on from the machine you're on), or
ending the existing logon (and logging on on the current machine).
This is technically the most challenging, but definitely the most friendly way - it ensures a user has only one session running, without being too obvious about it. And there is no bad blood with users unable to log in because they forgot to log out at work, etc.
Blizzard's World of Warcraft I believe implements this beautifully.
Basically, if you try to sign into the game after already being signed in, the first connection is kicked off.
This basically just entails making the session stored on the database. When you store the session data, store a username too. When a user logs in, delete any session records with that users name, and then create a new one for the person logging in.
I wouldn't suggest blocking 'new' people trying to log in, because users don't want to have to go back to another computer they have (possibly miles away) just because they forgot to log out.
There are also some other things you might have to think of. Things like sessionid hijacking. If a user just puts a cookie on their system (which is always possible) with the right sessionid, it is possible that they could use the same session on multiple computers. In which case you'd probably want to keep an IP field where you keep the data on who is currently logged on.
A typical approach to this problem is to use an
inactivity time-out period.
This system enforces a maximum number of logins per account, while allowing for the situation mentioned: a user left the office without logging out, and attempts to login from his/her home workstation.
Here are the general lines of such a system
Each account is associated with a number of concurrent logins (aka "seats") allowed (it seems the OP wished one and only one, for every account, but this could be more, and vary on an account basis).
The license manager logic keeps a list of all accounts/users currently logged-in, along with a time stamp with their "last" activity.
Before serving any page, the web application, calls the license manager (LM). The purpose is to allow the LM to update the timestamp of "last" activity, but also to deny the call in case the license was taken (more on this below)
Upon each login, the license manager logic verifies that the number of seats taken doesn't exceed the amount specified for the account.
If that is not the case, the LM simply adds the current session to the list of active session
If that is the case, the LM check for sessions in the list which are older than the time-out period. If one is found, it disables it, and grants access to the new login. If none is found, the login is denied.
upon each [explicit] log-out, the LM removes the corresponding session from the lists of active session.
Note that the general principle outlined above can have some variations, in particular:
rather than silently and systematically invalidating the [typically oldest] timed-out session, one can inform the user currently attempting to logging about this situation and let him/her decide of the need to "kill" such a session.
To avoid burdening the LM with each and every new page request, the web application can keep track on a per-session basis of the time since the session was last "refreshed" in the LM, and only call the LM if such time exceed say 1/3 of the time-out period.
Independently from the LM logic per-se, remember to keep a log of all the LM-related events (logins, logouts, inactive session "kills", refused logins...). Such logs should include the date/time, the IP address and other relevant info, and are useful when resolving issues associated with stolen passwords and such. Such logs also contain invaluable marketing, for example to find all accounts which appear to have too few seats (and could therefore purchase some ugrade), or to find at-risk accounts etc.
A few more considerations
make it easy for users to log-out (log-out button/link on most every page, at a fixed location
make it easy for users to report conflict / stolen password situation
Block the first login. If you log in at home, then in work, you don't want to be blocked, since this is a legit method. Always allow the login in the present, and drop the old ones.
I would suggest keeping track of whether each user is logged in and allowing the second login to end the first login's session.
Then allow the user whose session has ended to report possible fraudulent activity if they were kicked off in error.
Don't try to do it by counting the number of IP addresses a user has an active session from - some users may be behind load balanced proxies.
The solution is to write your own session handler - probably easiest with a database back end - and only allow one user to have one open session.
You might want to tune the session garbage collection and inactivity. You should also ensure that your system is immune from session fixation attacks.
C.
In terms of security, and this is what you're getting at, it is always a good idea to store session data in a database anyhow. Particularly if you're on a shared server.
In terms of which user to allow and which to knock off that is a matter for you to judge. I suppose you could have some secondary form of identification to make sure they are the real owner of the account. The one who actually signed up to it.
I've done this before in a web application that had the same requirement. Here's what I did:
When someone logs in, you generate a GUID and store it in your database, attached to the user. You also store this same GUID in a session cookie.
Every time a logged in user hits any page on your site, you check their cookie GUID and compare it with the GUID that is assigned to them in your database. If these GUIDs don't match, they've logged in on another machine, and you log them out from that session.
This method works really well.
how do you check if a user already has logged in?
so that if a user in another browser cant log in with the same account.
also, is this a good solution or should i let the user log in in the other browser and then log out the current user and display a message (you are logged in from another location) just like messenger does?
Using sessions is a good way to do this, and is a very common method for controlling authentication.
The flow usually looks something like this:
User visits site, and session_start() is called. A unique session identifier is set for that visitor (ie. a cookie).
User submits his login credentials to a login form
Login credentials are verified, and this fact is stored in the session data with $_SESSION['logged_in'] = true, or something similar
For the rest of the user's time on the site, you can check $_SESSION['logged_in'] to see if the user has logged in.
In order to control a user's logins, you could simply have a field in a database (users table is fine) indicating what the current session id is (retrieved with session_id()) for the user, and if it doesn't match the cookie value you just received, then you immediately call session_destroy() for that id, and consider the user as logged out.
Using $_SESSION means you don't have to worry about generating your own tokens, and gives you the power of the built-in superglobals to facilitate storing information about the user's authentication status.
Personally, I would allow multiple sessions to be active for a user for most web sites, as there's usually not a good reason not to, but it obviously depends on the nature of the site. However, storing the current active session id as mentioned above is a pretty simple way to accomplish this.
Generate a random token upon signing in (or use the sessionid), and store this in the database and in the users cookie. With each page access, ensure that the users token matches the database entry. If the two don't match, alert the user that they've logged in elsewhere.
You could also store the login time, which subsequently would be the time the token was assigned, and require 30 minutes before permitting another user to login with the same ID.
The first half of the question was answered well with how to detect the multiple users but how to treat them I think still needs a bit of work.
First if a user logs in correctly let them in, don't prevent them if they are logged on some other place. If you really don't want the user to have two open sessions then log out the old one or simply update the session id that you are saving so you can bounce out the old connection. You can inform if you want but I would only message the session that you invalidated. If you message the user logging in it becomes annoying when you are only dealing with the case of a user switching computers and they forgot to log out of the old session.
Well All solutions mentioned above will work but if on every page access you are making a call to database and checking for the session token to see weather its the same token assigned to user .. will kill your response time. what i'll suggest is use a caching mechanism instead of database in above said solutions. storing session token into database will add extra field to your database which is actually not required. Use open source caching solution like memcache.
you can make a table like userLoginStatus with fields like clockIn time & clockOut time,
and insert current time in clockIn when user is do login, leave clockOut time blank at that time, it should be updated only when user do clock over logout button,
so you can check specific user's current status, where clockOut is empty that user should be logged in. because it updated only when user do logout.