Home  >  Article  >  Backend Development  >  Analysis and use of PHP Session principles

Analysis and use of PHP Session principles

巴扎黑
巴扎黑Original
2016-12-05 09:53:391466browse

I have read an article called "Thorough Analysis of PHP Session Principles" before in a blog called Magic Lab. The author explained the changes in each link and related parameters during the code running process from the perspective of session usage. Settings and functions. I originally wanted to repost the original article, but the original blog was closed. I don’t know if it’s due to this large-scale re-filing or some other reason. Some original information was found through Baidu snapshots. Those not found will be reorganized according to previous understanding so that everyone can have a better understanding of the session.

Wedge: Session vernacular

Session, translated in English as "conversation", two people chatting, from the first sentence of hello to the last sentence of goodbye, this constitutes a conversation. Session in PHP mainly refers to the conversation between the client browser and the server data exchange, from the opening of the browser to the closing, the simplest session cycle. How do computer languages ​​generally implement conversations? To give a popular example:
The server is like a barber shop, and the client is like every customer who goes to get a haircut. Many barber shops have this kind of promotion method. Customers who consume 10 times in a row can get one for free. There are about three ways to do it. Implementation:
1. The barber has a good memory. He will know it at a glance after you have been here a few times - this is called the protocol itself supporting sessions;
2. Each guest is issued a membership card, and you must bring it with you every time you make a purchase. With this card, one purchase is recorded at a time, and of course a seal is required - this is called session realization through cookies. The disadvantage is that the security is not high. I can completely forge the membership card or official seal;
3. Prepare a big account in the barber shop In this book, each guest corresponds to a membership number or his or her own personal information, or even a password. When each guest comes to consume, he reports his membership number, and then records the number of consumptions in the big ledger - this is the session implementation of the session. Guests The member number in your mind is the SESSIONID saved on the client, and the big ledger is the session data saved on the server. Compared with the second method, the security is much higher, unless you say that you have changed your membership number and password. If you lose it, this is called forging the client's SESSIONID.

Because the http protocol is stateless, PHP can only implement sessions through the latter two methods. The former cookie has the disadvantages already mentioned and is not very secure, so important sessions will choose to use session. The session must rely on an identifier, which can also be understood as a password, which is SESSIONID. This is an encrypted string, stored on the client, usually in a cookie. Every communication between the client and the server is through this SESSIONID. The client first reports its home address, and then the server can find the session data you saved on the server. Continue the call.

Common session settings in php.ini

[Server]
session.save_handler = files
The default is file, which defines how the session is saved on the server. File means saving the session to a temporary file, if we want to customize it If you save in other ways (such as using a database), you need to set this item to user;

session.save_path = "/tmp/"
Define the location of the temporary file where the server stores the session.

session.auto_start = 0
If set to 1, there is no need to write session_start() in each file; session starts automatically.

session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
These three configuration combinations construct the garbage collection mechanism of the server-side session. session.gc_probability and session.gc_divisor constitute the probability of performing session cleanup. Theoretically The explanation is that the server regularly calls the gc function to clean the session with a certain probability. The probability of cleaning is: gc_probability/gc_divisor. For example: 1/100 means that when each new session is initialized, there is a 1% probability that the garbage collection program will be started. The standard for cleaning is the time defined by session.gc_maxlifetime.

[Client]
session.use_cookies = 1
The storage method used by the sessionid on the client. Setting 1 means using cookies to record the sessionid of the client. At the same time, the element $_COOKIE['PHPSESSIONID'] will be present in the $_COOKIE variable. Exists;

session.use_only_cookies = 1
also defines the storage method used by the sessionid on the client. Setting it to 1 means only using cookies to store the session ID. Generally speaking, clients now support cookies, so it is recommended to set it to 1 to prevent attacks related to passing session IDs through URLs.

session.use_trans_sid = 0
Corresponds to the above setting. If set to 1 here, it means that the sessionid is allowed to be passed through the url parameter. Similarly, it is recommended to set it to 0;

session.referer_check =
This setting is in session.use_trans_sid = 1, it will take effect. The purpose is to check the "Referer" in the HTTP header to determine whether the session id contained in the URL is valid. HTTP_REFERER must contain the string specified by this parameter, otherwise the session id in the URL will be regarded as invalid. Therefore, the default value is usually empty, that is, no checking is performed.

session.name = PHPSESSID
Define the name of sessionid, that is, the variable name. You can view the value of PHPSESSID through the browser http tool;

session.hash_function = 0
Select the encryption method of session_name, 0 represents md5 encryption, 1 represents sha1 encryption, the default is 0, but it is said that encryption using sha1 method is more secure;

session.hash_bits_per_character = 4
Specify each character in the session_name string How many binary numbers are stored in it? These binary numbers are the results of the hash function.
4 bits: 0-9, a-f
5 bits: 0-9, a-v
6 bits: 0-9, a-z, A-Z, "-", ","

url_rewriter.tags = "a=href,area= href,frame=src,input=src,form=,fieldset="
Specify which HTML tags to rewrite to contain sid(session_id) (only valid if "session.use_trans_sid" is turned on), the URL rewriter will add A hidden "" that contains additional information that should be appended to the URL.

session.cookie_lifetime = 0
The life cycle of the cookie file that saves the sessionid. If set to 0, it means the session is over, and the sessionid will disappear automatically. If you force close the browser, the last sessionid will be lost;

session. cookie_path = /
Save the location of the sessionid cookie file on the client;

session.cookie_domain = /
Save the domain name setting of the sessionid cookie. This is related to the access permission setting of the domain name allowed by the cookie. Generally speaking, you want to have all the domain names of your website The client's cookie can be accessed in all directories, so it should be set to "/". If you need to know more, you can see the related settings and usage of the domain parameter of the setcookie() function;

session.bug_compat_42 = 1
session.bug_compat_warn = 1
These two settings, which can be said to be almost abandoned, are for the old version of PHP. They are mainly for the session_register function. Because the register_global of PHP5 is turned off by default, the session_register function is not used at all in PHP5. ; And php6 will abolish this setting and directly define it as closed, so there is no need to study these two;


session_start() What does session_start() do?

Assume that several key parameters of the session in php.ini are configured as:
session.save_handler = files
session.use_cookies = 1
session.name = PHPSESSID
session.save_path = "/tmp/"

Pass below The code sample illustrates the role of session_start during a session.

Program 1:
session_start();
$_SESSION['uname'] = 'monkey';
$_SESSION['ukey'] = 20119999;
?>


After execution of program 1 , session_start() will do two things:


1. Generate a cookie file on the client to store the PHPSESSID. The storage location and storage method of this file are related to the execution method of the program. Different browsers are also different. This step will generate a serialized string - PHPSESSID; check the cookie information in the browser and install relevant plug-ins. httpfox, web developer, etc. in firefox are all very good tools.


2. Generate a temporary file on the server to store session data. The storage location is specified by the session.save_path parameter. The name is similar to "sess_85891d6a81ab13965d349bde29b2306c". "sess_" means that this is a session file, "85891d6a81ab13965d349bde29b2" 306c" is this session The PHPSESSID is the same as the client's PHPSESSID value.
Open the "sess_85891d6a81ab13965d349bde29b2306c" file with an editor, and you will see a string of content like "uname|s:6:"monkey";ukey|i:20119999;". What is stored in this file is the specific content of the $_SESSION variable. Each variable is separated by a ";" semicolon.


The format is: variable name | variable type: [length] : value; For example: uname|s:6:"monkey"; means that the type of SESSION variable uname is string, the value length is 6, and the value is monkey.

Then the question is, are the two things mentioned above completed when the program is executed to session_start()? Between these two things, who comes first and who comes last?
Let the experiment prove it, change the program slightly:

Program 2:
session_start();
$_SESSION['uname'] = 'monkey';
$_SESSION['ukey'] = 20119999;

sleep(30);
?>

First delete all session data on the client and server, then execute program 2, and take advantage of the 30 seconds of sleep in the program to check the session status on the client and server. Discovery: During the execution of the program, the client did not create a cookie file to save the PHPSESSID, but the server already had a temporary file to save the session content, but there was no content in the file. After 30 seconds, the client's cookie file will be generated, and the content will be in the session file on the server side.


It can be inferred that the general process should be: when the program is executed to session_start(), the server first generates PHPSESSID and the corresponding session file, but when the program assigns $_SESSION, the corresponding value is not Written into the session file, let's assume it is stored in the memory. After the program is executed, a cookie file saving the PHPSESSID will be generated on the client, and the value in the $_SESSION variable will be written into the session file on the server. As for who goes first and who comes last in the last two steps, I haven't thought of a good way to prove it yet.


In order to further demonstrate, delete the session-related content on the client and server and execute program 3, and observe the results of the first and second times:
Program 3:
session_start();
$_SESSION[ 'uname'] = 'monkey';
$session_id = session_id();
$sess_file = "/tmp/sess_".$session_id;
$content = file_get_contents($sess_file);

echo '***'. $_COOKIE['PHPSESSID'] .'***';
echo '
' . $_SESSION['uname'] . '
';
echo '***'. $content.'***';
?>


The above is the execution method of sessin_start() for the first time, that is, what is done when the first session_start() appears in a set of programs , let’s look at the subsequent session_start():

Assumed php.ini configuration: session.cookie_lifetime = 0

Program 4:
session_start();
echo $_SESSION['uname'];
echo $_SESSION['ukey'];
?>

Now, the client already has a cookie file that saves the PHPSESSID, and the server also has a sess_ file that saves the session content. Execute program 4, and normal content will be printed out. . At this time, if you forcefully close the browser and then execute program 4, what will be the result?

First of all, session.cookie_lifetime is set to 0, which means that the lifetime of the cookie file saved by the client PHPSESSID is 0. If the browser is open, the value of PHPSESSID will be saved in the memory. Once it is forcibly closed, the value of PHPSESSID will be saved. The cookie file will be destroyed at the same time, but the server does not execute session_destroy(), so the session data file on the server is still there, but when the browser opens execution program 4 again, it is found that nothing is output, so the reasoning is:


session_start () First, it will obtain the PHPSESSID in the client cookie, then form a file name with "sess_", go to the server to find the file, then take out the contents of the file, and put the contents into the $_SESSION global variable for use. If the browser is forcibly closed and reopened, the previous PHPSESSID is lost. Encountering session_start() at this time is equivalent to the first execution mentioned above, and a new PHPSESSID will be generated. This PHPSESSID cannot match the sess_ file of the previous server. , so the content cannot be retrieved. Of course, the server also has a file that matches this PHPSESSID, but that file is still empty.


So, in order to realize the mechanism that the same user can only log in on one machine or even one browser, some systems will have a problem in the server-side session lifetime after the browser is forcibly closed if the setting of session.cookie_lifetime is not modified. If the user cannot log in before the deadline, a better way is to set session.cookie_lifetime to a relatively large value. Anyway, it will have no effect if a cookie file exists for a longer time.


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn