This section will use PHP and Redis to implement user registration login function, the following sub-module to describe the implementation method.
1. Registered
Requirements Description: Users need to submit email, login password and nickname when registering. Where the mailbox is the user's unique identity, each user's mailbox cannot be duplicated, but allows the user to modify his or her mailbox.
We use hash types to store the user's data, and the key name is User ID. Where the user ID is a self-increasing number, the ID is used instead of the mailbox as the user's identity because the user's identity may be associated with the users object in other keys, and if the mailbox is used as the user's identity, the user will have to modify a large number of key names or key values at the same time when they modify the mailbox. To minimize the need to modify, we only use the mailbox as a field of the hash key. To do this, you also need to use a hash type key email.to.id to record the correspondence between the mailbox and the user ID so that you can get the user's ID through the mailbox at logon.
After the user fills out and submits the registration form, we first need to verify the user input, we create a register.php file in the project directory to implement the logic of user registration. The code for the validation section is as follows:
Set Content-type so that the browser can display prompt information using the correct encoding,
The specific encoding needs to be selected according to the actual file encoding, here is utf-8.
Header ("content-type:text/html; Charset=utf-8 ");
if (!isset ($_post[' email ') | |
!isset ($_post[' password ') | |
!isset ($_post[' nickname ')) {
Echo ' Please fill in the complete information. ‘;
Exit
}
$email = $_post[' email '];
Verify that the user submitted the mailbox is correct
if (!filter_var ($email, Filter_validate_email)) {
Echo ' mailbox format is not correct, please re-check ';
Exit
}
$rawPassword = $_post[' password ');
Verify that user-submitted passwords are secure
if (strlen ($rawPassword) < 6) {
Echo ' for security, the password length is at least 6. ‘;
Exit
}
$nickname = $_post[' nickname ');
Different sites have different requirements for users ' nicknames, which are no longer checked, even if they are empty.
Then we need to determine whether the user submitted the mailbox has been registered:
$redis = new Predis\client ();
if ($redis->hexists (' email.to.id ', $email)) {
Echo ' The mailbox has been registered. ‘;
Exit
}
After the verification is passed, the user data needs to be credited to Redis. Remember to use the hash function to handle user-submitted passwords when storing, and to avoid storing plaintext passwords in the database. The reason is that if the data in the database is compromised (either for external or internal reasons), the attacker will not be able to obtain the user's real password and will not be able to log into the system properly. It is more important to consider that users are likely to use the same password in other sites, so the plaintext password disclosure will also cause additional damage to the user.
In addition, avoid using a faster hash function to handle passwords to prevent attackers from using brute-lifting to crack passwords, and to generate a random "salt" for each user to avoid the use of rainbow table crackers. Here, as an example, we use the bcrypt algorithm to hash the password. the crypt function provided in PHP 5.3 supports the bcrypt algorithm, and we can implement a function to randomly generate salt and call the Crypt function to obtain the hashed password:
function Bcrypthash ($rawPassword, $round = 8)
{
if ($round < 4 | | $round >) $round = 8;
$salt = ' $2a$ '. Str_pad ($round, 2, ' 0 ', str_pad_left). ' $ ';
$randomValue = Openssl_random_pseudo_bytes (16);
$salt. = substr (Strtr (Base64_encode ($randomValue), ' + ', '. '), 0, 22);
Return crypt ($rawPassword, $salt);
}
Tip The Openssl_random_pseudo_bytes function requires the installation of the OpenSSL extension.
After that, use the following code to obtain the hashed password:
$hashedPassword = Bcrypthash ($rawPassword);
Storing user data is simple, and all commands are described in Chapter 3rd. The code is as follows:
Require './predis/autoload.php ';
$redis = new Predis\client ();
First get a self-increment user ID
$userID = $redis->incr (' Users:count ');
Storing user information
$redis->hmset ("user:{$userID}", Array (
' Email ' = $email,
' Password ' = $hashedPassword,
' Nickname ' = $nickname
));
Remember to record the correspondence between the mailbox and the user ID
$redis->hset (' email.to.id ', $email, $userID);
Prompt user to register successfully
Echo ' Registration is successful! ‘;
In most cases we need to verify the user's mailbox when registering, but this part of the logic is similar to the Forgotten password section, so there is no more introduction here.
2. Login
Requirements Description: Users need to submit the mailbox and login password, if the correct output "login successful", otherwise the output "user name or password error."
When a user submits a mailbox and login password, first obtains the user ID through the email.to.id key, then hashes the user's submitted login password with the same salt and the password compared to the database store, if the same means the login succeeds. We create a new login.php file to handle the user's login, and some of the code to process the logic is as follows:
Header ("content-type:text/html; Charset=utf-8 ");
if (!isset ($_post[' email ') | |
!isset ($_post[' password ')) {
Echo ' Please fill in the complete information. ‘;
Exit
}
$email = $_post[' email '];
$rawPassword = $_post[' password ');
Require './predis/autoload.php ';
$redis = new Predis\client ();
Get the user's ID
$userID = $redis->hget (' email.to.id ', $email);
if (! $userID) {
echo ' username or password is incorrect. ‘;
Exit
}
$hashedPassword = $redis->hget ("user:{$userID}", ' Password ');
Now that we have the hashed password that we previously stored, we define a function to hash the user's submitted password. The password returned in the Bcrypthash function already contains salt, so only the hashed password is required as the second parameter of the Crypt function, and the crypt function automatically extracts the salt from the password:
function Bcryptverify ($rawPassword, $storedHash)
{
Return crypt ($rawPassword, $storedHash) = = $storedHash;
}
You can then use this function to do the comparison:
if (!bcryptverify ($rawPassword, $hashedPassword)) {
echo ' username or password is incorrect. ‘;
Exit
}
Echo ' Login successful! ‘;
3. Forgot password
Requirements Description: When the user forgets the password can enter their own mailbox, the system will send a link to change the password of the message, the user click the link will go to the Password modification page. The module's access frequency is limited to 1 minutes and 10 times to prevent malicious users from using this module to send large amounts of spam to an email address.
When the user enters the mailbox on the Forgotten Password page, our program needs to do two things.
(1) Frequency limit of access. Here are the methods used in the 4.2.3 section to limit the frequency of access to the process of sending a password change message using the mailbox identifier. When the user submits the e-mail address, first verify that the email address is correct, and if it is correct, check that the access frequency is overrun:
$keyName = "rate.limiting:{$email}";
$now = time ();
if ($redis->llen ($keyName) < 10) {
$redis->lpush ($keyName, $now);
} else {
$time = $redis->lindex ($keyName,-1);
if ($now-$time < 60) {
echo ' access frequency exceeds the limit, please try again later. ‘;
Exit
} else {
$redis->lpush ($keyName, $now);
$redis->ltrim ($keyName, 0, 9);
}
}
Generally, there is also a frequency limit for IP addresses in the entire station, similar in principle.
(2) Send a password change email. After the user is restricted by the frequency of access, we generate a random verification code for it and send the verification code to the user via email. At the same time in the program to the user's mailbox address is named Retrieve.password.code: hash of the code string type key, and then use the expire command to set a time-to-live (such as 1 hours) to provide security and ensure the timely release of storage space. Because forget password need security level and user registration login same, so we still use the bcrypt algorithm to hash The verification code, the specific algorithm is no longer detailed above.
Redis Practice: User Registration Login function