This article analyzes the login process of Yii framework in detail. Share it with everyone for your reference. The specific analysis is as follows:
Yii is a bit difficult for novices to get started, especially about sessions, cookies and user authentication. Now let’s talk about the login process in Yii and talk about some general knowledge on how to set up session, cookie and user authentication in Yii development
1. Overview
Yii is a full-stack MVC framework. The so-called full-stack refers to the fact that the Yii framework itself implements all functions used in web development, such as MVC, ORM (DAO/ActiveRecord), globalization (I18N/ L10N), caching, jQuery-based AJAX support, role-based user verification (authentication and role-based access control), program skeleton generator (scaffolding), input validation (input validation), Form widgets (widgets), events (events), themes (theming), web services (Web services), logging (logging) and other functions. See the official description for details.
What I want to talk about here is just the login process of Yii. To develop with Yii, you usually use a console tool called Yii shell to generate the skeleton of a program. This skeleton assigns us the basic structure of developing web programs according to the MVC method. And it is a program that can be run directly. If you know Ruby on Rails, the principle is the same.
2. Website login process
There is a protected directory in the generated program. There is a file called SiteController.php in the controllers directory below. This file is automatically generated and contains a file called actionLogin. The program login process starts from the beginning by default. Yii Transfer an address similar to http://domain.com/index.php?r=site/login to the actionLogin method mentioned above through a component called router. The function of this route is not the focus here. actionLogin The code of the method is like this.
First initialize a LoginForm class, and then determine whether it is a request after the user clicks login (check whether there is POST data in the request). If so, first verify the input ($model->validate) and then try to log in ($ model->logiin), if all are successful, jump to the page before login, otherwise the login page will be displayed.
3. Framework login process
The LoginForm class inherits from CFormModel and indirectly inherits from CModel, so it provides CModel to provide some functions such as verification and error handling. The login method is to perform verification operations. The method first passes the user name and password provided by the user Generate a UserIdentity class to represent the user entity. The authenticate method in this class performs actual verification actions, such as determining whether the user name and password match from the database. The login method of the LoginForm class determines whether the login is successful by querying whether there is an error in authenticate. Success. If successful, execute the Yii::app()->user->login method to allow the user to actually log in to the system. The processes mentioned above are provided by the user program, and Yii::app( )->user->login, that is, the login method of CWebUser is a process provided by the Yii framework. Let's take a look at what it does. The following is the code in this regard, located in the (Yii)webauthCWebUser.php file.
The parameter $identity is the UserIdentity class generated when logging in above, which contains basic user information, such as the above Id, Name, and possibly other customized data getPersistentStates. The program first copies the data in $identity In the example of CWebUser, this process includes generating the corresponding session. In fact, the main purpose is to generate the session. Then based on the parameters $duration (the time the cookie is saved) and the allowAutoLogin attribute, it is judged whether to generate a cookie that can be used to automatically log in next time. If so, generate a cookie (saveToCookie).
First, create a new CHttpCookie. The key of the cookie is obtained through the getStateKeyPrefix method. This method returns md5('Yii.'.get_class($this).'.'.Yii::app()->getId() by default ); that is, the class name and the Id of CApplication, and this Id is a value generated by the crc32 function. It does not matter what the specific value is. But it will generate the same value every time. Then set expire, the expiration time of the cookie, and then Create a new array that contains basic data. Then the more important thing is to calculate the value of the cookie, $app->getSecurityManager()->hashData(serialize($data)), getSecurityManager returns a CSecurityManager object, and calls hashData Method.
protected function computeHMAC($data){
if($this->_validation==='SHA1'){
$pack='H40';
$func='sha1';
}
else{
$pack='H32';
$func='md5';
}
$key=$this->getValidationKey();
$key=str_pad($func($key), 64, chr(0));
return $func((str_repeat(chr(0x5C), 64) ^ substr($key, 0, 64)) . pack($pack, $func((str_repeat(chr(0x36), 64) ^ substr($key, 0, 64)) . $data)));
}
hashData calls the computHMAC method to generate a hash value. There are two hash algorithms: SHA1 and MD5. The default is SHA1. When hashing, a verificationKey (verification code) is also generated, and then the verification code and the hash to be The value undergoes some deliberately arranged operations and finally generates a 40-bit SHA1 hash value. The hashData method ultimately returns the hash value generated by computeHMAC and the string generated by the serialized original data. This process may be questionable. Why do we need a verification code?
Let’s first take a look at how cookie-based authentication works. The server generates a cookie and sends it to the browser, and saves it in the browser for a period of time based on the expiration time. Each time the user accesses this website through the browser Cookies are always sent with the HTTP request. This is part of the http protocol and has nothing to do with language and framework. The server determines whether the user can be regarded as a logged-in user by judging the cookie sent. But the cookie is the client's It is sent by the client browser or even other programs, which means that the cookie sent may be fake and tampered with. Therefore, the server needs to use some verification mechanism to determine whether it is a cookie sent by itself later. This verification mechanism is The cookie contains a hash value and the original data that generated the hash value. After receiving the cookie, the server takes out the original data, and then generates a hash value according to the original method to compare with the sent hash value. If it is the same, it trusts the hash value. cookie, otherwise it will definitely be an illegal request. For example, my Yii website generated such a cookie:
cookie name:b72e8610f8decd39683f245d41394b56
cookie value: 1cbb64bdea3e92c4ab5d5cb16a67637158563114a%3A4%3A%7Bi%3A0%3Bs%3A7%3A%22maxwell%22%3Bi%3A1%3Bs%3A7%3A%22maxwell%22%3Bi%3A2%3Bi %3A3600%3Bi% 3A3%3Ba%3A2%3A%7Bs%3A8%3A%22realname%22%3Bs%3A6%3A%22helloc%22%3Bs%3A4%3A%22myId%22%3Bi%3A123%3B%7D%7D
Cookie name is an md5 value uniformly generated by the website. The value of cookie value is two parts, which is a string generated by the hashData method. The first part is the hash value, and the second part is the original value. In other words, the previous 1cbb64bdea3e92c4ab5d5cb16a67637158563114 is The hash value is followed by the original value. This hash value is a 40-bit string generated using SHA1. The server hashes the original value through an algorithm to produce a value and compares it with the passed hash value to know whether it is legal and does not review illegal requests. Okay. What about the verification code?
If the server simply hashes the original value directly with SHA1 or MD5, the person who sent the request can modify the original value and hash value at will to pass the server's verification. Because the SHA1 algorithm is public, everyone Everyone can use it. Therefore, the server needs to add a verification code that the client does not know when hashing to generate a hash value that the client cannot get the correct hash from the original value (a bit convoluted:) ). This is what requires a verification code. Reason. And this verification code must be universal for the entire site, so the above getValidationKey method generates a unique verification code for the entire site and saves it. By default, the verification code is a random number and is saved in (yii) runtimestate. bin file. This will be the same for every request.
The end of the login process is to send the generated cookie to the browser. It can be used for verification the next time you request it.
I hope this article will be helpful to everyone’s PHP program design based on the Yii framework.