2

For my personal education, I am trying to create a secure login system using cookies. I have read a lot of articles and Stack Overflow questions on how to achieve that, but couldn't find anything useful. Everyone is suggests different ways of achieving that, but those who seem reasonable and know what they are doing, I cant quite understand for some reason.

Can you please explain me, what is the best way to create a secure login system with cookies?

I have heard, that the best approach is tokens. But some people say, that you should add a token next to the user id in the token table in the database - and so what if a person logs in from different devices? Some say, you should track IP addresses for that - and so what if a person logs in from another IP? Some say, you should create a session and a cookie - but then what's the point of the session (if the cookie authenticates a person)...

I have seen a lot off questions where people asked similar questions, and in the answers, people were trying to explain what is the difference between cookies and sessions. I know all of the differences and all of the theory. I just cant understand the technique to make everything secure.

I just cant clearly understand how that system should logically work, so can you please explain that step by step to me?

closed as too broad by Steffen Ullrich, Xander, Adi, SilverlightFox, Rory Alsop Dec 10 '15 at 13:20

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    Hi, I think the reason you hear so many different suggestion is because the notion of secure login is relative. I think first you need to think about what are the potential threat you wish to protect against. – wei Dec 9 '15 at 4:54
  • @wei Information stored in cookies can be modified or spoofed, so it is insecure to store ids and passwords there. I am looking for a technique, for example using tokens, with which I can send a cookie to a person's computer not being worried, that it can be spoofed. – Tack Dec 9 '15 at 4:57
  • Usually credentials aren't stored in cookies. Instead, usually a different token is sent from the server in the cookie before and after the user login using the credentials. But there are more than just that. For example, when you say some told you about tracking IP, that is a different layer of additional protection all together. – wei Dec 9 '15 at 5:03
  • @wei I guess I found a solution. So basically I need to create a random unique token, store it in he cookie. Then place it in the database with the user's id. When the user visits the web site, I should open a session based on the user's id, that I got from the database using the Cookie's token. When session expires, the programm checks again for the token. When a person logs out, the database entry and the cookie should be destroyed. Each user has different tokens and multiple rows in the login db table (cause he can be logged in from different devices). Is this the write technique? – Tack Dec 9 '15 at 5:12
  • Why are you doing this Tack? Is it a homework problem? For a job requirement? Personal use? Knowing would help us better answer your question. – Neil Smithline Dec 9 '15 at 5:16
3

In PHP, creating a session is easy. You first declare it using session_start(). It handles creating a session cookie for you, and pretty much all of the hard stuff. When the user navigates throughout your site, you can read from and write to the session variables using the $_SESSION global object, which can affect which content you want to display to the user, and even how it is displayed.

What happens, is the server generates a secure random token on its side and then sends the value as a cookie to the client which the client automatically communicates back to the server on each request. The server takes this value and uses it to determine which object in memory to reference as the $_SESSION object.

However you want to handle the initial login is up to you -- I'm not going to get into that here. But once the user does log in, you want to indicate that in the $_SESSION global. In order to make it secure you will want to destroy any existing session and create a new one on authentication. The way I usually do it is I set $_SESSION['user'] on login (after destroying the previous session and creating a new one). That way it has another use, checking whether a user is logged in: if(isset($_SESSION['user'])).

This is basic functionality, but hopefully it points you in the right direction. Databases aren't necessary for sessions unless you're trying to implement logon/session policies or you're running your website in a cluster. That would be due for a more complicated discussion which I don't think would be appropriate to get into here.

Edit/Update:

It turns out I will in fact get into the specifics of a secure login system; If you want your login system to be up to standards in terms of security, you will need to properly hash (and salt) your password. It turns out there is a PHP method for that as-well.

Hashing basically turns whatever the input is into garbage that can't be turned back into the original input. Password hashing is used to prevent people from gaining access to the original password in the case of a server/database compromise where passwords can be potentially leaked. The most important thing to know when hashing is that the slowest algorithms work the best for passwords.

Salting is almost equally as important as the algorithm used to secure the passwords. The salt is a CSPRNG which simply gets added to the password before hashing. CSPRNG stands for Cryptographically Secure Pseudo Random Number Generator, and it's really just a fancy way of saying that it's a super random and unpredictable set of bytes. These bytes are randomly generated on a per-password basis to protect end-users against rainbow attacks, in which a single produced hash can be checked against large quantities of passwords. By requiring a single hash per attempt per password, it greatly reduces the chances of mass a password leak resulting from a mass hash leak.

A manual system would work as-follows:

When the user account is created, a row is inserted into the database 'users' with the username specified, and the hashed password. The hashed password is first salted (random data added to the password), then hashed using a slow password hashing algorithm. The salt is additionally added to the password hash before being inserted into the database. Optionally you may store something to identify the hashing algorithm used with it as-well. If you feel uncomfortable combining these values, you can also store them as separate database values.

When the login process is initiated, the database is queried in the 'users' table for the row with the key 'username' matching the username requested. That row is pulled which includes the password hash. First, the salt is taken away from the hash. Then the salt is added to the password given during authentication and that whole thing is hashed using the same hashing algorithm used originally. Then, if the end result matches the hash that is stored, the user can be successfully authenticated.

I hope I'm not confusing you too much with my explanations. Ashley Madison apparently missed the memo entirely so if you don't understand, don't feel bad. You're not a multi-million-dollar website. The most issues come from when people take it upon themselves to accomplish things beyond their skill-set. In that regard I certainly recommend that you use the built-in, or at least open-sourced and publicly recommended password hashing functions whenever possible. They take all of the guesswork out of the equation.

-8

What I do is md5 hash the password then salt it to protect against rainbow tables, and store two cookies on the user's computer. One with the userid and another with the salted password. To protect against brute force, I log unsuccessful login attempts, so if someone changes the password cookie to something wrong, it's logged. 100 wrong attempts means the person cannot login again to that account for 24 hours.

I make the salt different for each user, so password x will give a different result in row 1 than it would in row 2. If someone checks the cookies, they won't be able to figure out your username, email or password.

Doing proper research, I found that this is a secure way to run an authentication system. Other websites make it more complicated by having the cookie be a random string, but that string has to be checked against the database even if that random string isn't anywhere in the database, so an algorithm is used to convert the logged in user's database row into a random string to authenticate them.

  • Comments are not for extended discussion, and this looks like a full on education in correct use of password hashing. Please continue it in chat. – Rory Alsop Dec 10 '15 at 13:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.