Identification and Authentication Published the 2019-08-18 Identification is recognizing that a given user is who they claim to be, whereas authentication is actually confirming that what they're saying is right. Those are two strictly different notions. - An email, or a username, is made to identify a user. - A password is made to authenticate this person. > I'll take the example of a users table with username and password. ## Bad idea: Using passwords for identification When you have your users table in your database, you have their username in clear text, so you can identify them (find the corresponding row associated to them). What you musn't do, however, is to try to identify them based on *their password*. Remember: a password is an **authentication** mechanism, not an **identification** one. The following SQL request to try to log in a user is then inherently wrong. ```php prepare( "SELECT id FROM users WHERE username = ? AND password = ?"); $stmt->execute([$username, $password]); ``` Not only it is wrong because it uses the password as an identification mechanism (as opposed to an authentication mechanism), but it also forces the developer to ignore password storing standards, as the stored password will forcibly be stored using an unsuitable, and unsecure, mechanism. > Yes, I'm really hammering the difference between identification and > authentication, as it's a core concept here. ## Good idea: Only using the identifier for identification As we saw, a user is identified by his username in our example above. The good solution is then to try to find a row identified by this username, and then only to verify the password against the stored secure value. As an example, the snippet below demonstrates a proper mechanism. ```php prepare("SELECT id, password FROM users WHERE username = ?"); $row = $stmt->execute([$username])->fetch(PDO::FETCH_ASSOC); $can_log_in = password_verify($password, $row['password']); ``` The `$can_log_in` variable will be set to true if the right username/password combination have been entered, and false otherwise. > Note that for the example's sake, we omit error verification for the request, > which obviously shouldn't be done on a real website.