Menu
Is free
check in
the main  /  the Internet / Session. Monitoring sessions, application passwords and entry confirmation on Facebook Active session

Session. Monitoring sessions, application passwords and entry confirmation on Facebook Active session

The web server does not support a permanent connection with the client, and each request is processed as new, without any connection with the previous one.
That is, it is impossible to track requests from the same visitor nor save variables for it between viewing individual pages. Here, to solve these two tasks, sessions were invented.
Actually, the session, if in a nutshell - this is a mechanism that allows you to unambiguously identify the browser and creating a file for this browser on the server in which the session variables are stored.

I will not paint in detail in such a mechanism. These are such a traveler case, as a shopping cart in the e-store, authorization, as well as not quite trivial problems, such as the protection of interactive parts of the site from spam.

In principle, it is quite easy to make your own analogue of sessions, not as functional as built into PHP, but similar in essence. On cookies and database.
When prompted the script, we see whether Cook came with a certain name. If there are no cookies, then put it and write a new line to the database with the user data. If there is a cook, we read the data from the database. We remove old records from the base from the base and here we are ready for the session mechanism. It is completely easy. But there are some nuances that prefer the use of the embedded mechanism of sessions.

If only the first is enabled, then when you start the session (each time you call session_start ()) Cook is installed to the client. The browser properly at each request this Cook returns and PHP has a session identifier. Problems begin if the Cook browser does not return. In this case, without receiving cookies with an identifier, PHP will start a new session all the time, and the mechanism will not work.

If only the second is included, then the Cook is not exhibited. And it happens, for what, mostly, actually, it is worth using the built-in session mechanism. After the script does its work, and the page is fully formed, PHP views it all and adds to each link and to each form to transmit the session identifier. It looks like this:
Index turns into
Index
and the forms add a hidden field

And the browser when clicking on any link, or when you click on the button in the form, send us a variable in the query - the session identifier!
For obvious reasons, the identifier is added only to relative links.

Theoretically, in our homemade sessions on cookies and the database with you, you can attribute to all references to the ID - and then our own sessions will work independently of Cook. But, you see - more pleasant when someone else does this work? ;-)

Default B. recent versions PHP includes both options. How does PHP come in this case? Cook is always exhibited. And link links only only if the RNR did not find a cook with a session identifier. When the user in the short time for this session comes to the site, it is made by Cook, and the links are complemented. The next time you request, if cookies are supported, PHP sees Cook and ceases to complement the links. If cookies do not work, then PHP continues to properly add the ID to the links, and the session is not lost.
Users who have cookies will see a long link from the ID only once.

Fuh. With the transfer of the identifier finished.
Now it remains to tie a file with data on the server side.
PHP will do it for us. Just write enough
session_start ();
$ _Session ["Test"] \u003d "Hello World!" ;

And PHP will write to a file associated with this session, the TEST variable.
Here is a very important remark.
Array $ _Session. - Special.
In it, in fact, there are variables that we go to make accessible in various scripts.
To put a variable in the session, it is enough to assign it an array element $ _session.
To get its value - it is enough to apply to the same item. An example will be slightly lower.

Garbage garbage - removal of obsolete pHP files Also engaged in himself. As with the coding of data and a bunch of any other necessary things. As a result of this concern, work with sessions turns out to be very simple.
So we, in fact, come to the example of the work of the sessions.
The example is very small:
session_start ();

echo. "You updated this page". $ _Session ["Counter"] ++. "Once.";
echo "
update ";
?>

We check whether we have a Counter variable in the session, if not, then we create it with a value of 0, and then we derive its value and increase the unit. The enlarged value is recorded in the session, and the next time you call the script, the variable will be 1, and so on.
Everything is very simple.

In order to have access to a variable session on any pages of the site, you need to write only one (!) Location at the very beginning of each file in which we need sessions:
session_start ();
And further access the elements of the $ _session array. For example, the authorization check will look something like this:
session_start ();
if ($ _session ["authorized"]<> 1 ) {
header ("location: /auth.php");
exit;
}

Remove variables from the session.
If you have register_globals \u003d off, then you can write
unset ($ _ session ["var"]);
If not, then nearby It is necessary to write with it
session_unregister ("var");

The most common mistakes that give PRP when trying to work with sessions are:
Two of them,
Warning: Cannot Session Cookie - Headers Already Sent
Warning: Cannot Session Session Cache Limiter - Headers Already Sent

caused by the same reason, the solution is described in this fak
Third
Warning: Open (/ TMP \\ SESS_SID, O_RDWR) Failed: No Such File Or Directory (2) in Full_Script_path on Line Number (earlier she looked like Warning: Failed to Write Session Data (Files). Please Verify That The Current Setting of Session.Save_path IS Correct (/ TMP)),
If you translate it from English, explains in detail the problem: the path specified in PHP.ini is unavailable to the directory in which the session files are written. This error fixes the easiest way. Just register the directory that exists and is available for recording, for example,
session.save_path \u003d C: \\ Windows \\ Temp
And do not forget to reboot Apache after that.

As it turns out, the intelligence of human has no limits, and therefore I have to clarify:
A third error message (it is impossible to find a directory) will inevitably lead to the appearance of the first two, since the error message is the output to the browser and after it is impossible to use headers. Therefore, do not rush to seek premature conclusion, and first write the right way!

The next prevalence problem when working with sessions is a heavy legacy register_globals. Do not give the script variables the names that match the indexes of the $ _session array!
When register_globals \u003d on, the values \u200b\u200bwill overwrite each other, and you are confused.
And when register_globals \u003d OFF another error will appear: "Your Script Possibly Relies On a Session Side-Effect Which Existed Until PHP 4.2.3.", In the event that there is a variable session in the script, and the global variable with the same name . To get rid of it, you should always initialize variables before use (or at least check for existence) and not to give global variable names that match the indexes of the $ _session array.

If it does not work, but no messages are displayed, then add two lines to the very beginning of the script that are responsible for the output of all errors on the screen - it is quite possible that there are errors, but you just don't see them.
ini_set ("display_errors", 1);
error_Reporting (E_ALL);

Or see errors in Error_log. In general, the topic of displaying error messages is beyond the scope of this article, so just make sure at least you can see them. Slightly turning about the search for errors can be found in this section.

If you are sure that there are no errors, but the above example does not work anyway, then it is possible that the PHP is not included in the PCL pass through the ul, and cookies for some reason do not work.
See what you have with cookies.
In general, if you "don't work" sessions, first try to transfer the identifier of the session with your hands, that is, make a link and attribute to it identifier:
session_start ();
if (! Isset ($ _ session ["Counter"])) $ _session ["Counter"] \u003d 0;
echo. "You updated this page". $ _Session ["Counter"] ++. "Once.

update ";
?>

It should be verified that the session.use_only_cookies directive is not enabled, which prohibits PHP to accept the session identifier if it was transmitted via the URL

If this example does not earn, then the problem is either in banal typos (Half "problems" with sessions comes from an incorrectly written variable name), or in too old version PHP: Support for sessions appeared in version 4.0, and an array $ _Session. - in 4.1 (before that was used $ Http_session_vars).
If it works, then the problem is in cookies. Tracking - what a bunch is put by the server to the browser, whether the browser returns it. Search is very helpful, looking through viewing the exchange of HTTP headers between the browser and the server.
The explanation of the principle of work of the Cook goes beyond the scope of this and so too large text, but at least make sure that the server of the Cook with the identifier sends, and the browser returns. And at the same time identifiers coincide with each other \u003d)
Installing cookies should look like
Set-Cookie: PHPSESSID \u003d PRLGDFBVLG5FBSBSHCH6HJ0CQ6;
or how
Set-Cookie: PHPSESSID \u003d PRLGDFBVLG5FBSBSHCH6HJ0CQ6; path \u003d /
(if you request a script not from the root catalog)
Server response should look like
Cookie: PHPSESSID \u003d PRLGDFBVLG5FBSBSHCH6HJ0CQ6
or
Cookie: PHPSESSID \u003d PRLGDFBVLG5FBSBSHCH6HJ0CQ6; B \u003d B.
If the browser returns other cookies, except the session identifier.

If the bouquet browser does not return - check whether cookies work at all.
Make sure the domain to which you appeal is to have a normal name (in which there is at least one point and does not contain prohibited characters, such as underlining) and clean the browser cache - these are two main reasons for Cookies may not work.

If an example works from here, and your own code is not, then the problem is obviously not in sessions, but in the algorithm. Look for where you lost the variable, over the steps endure an example from here, debug your script.

Another problem may occur if you use redirection via Header or navigation using JavaScript.
The fact is that RNR automatically adds the session identifier only to the references of the species But does not make it for header-s, javascript, meta tags.
Therefore, you need to add the identifier with your hands, for example, as follows:
header ("Location: /Script.php?" Session_name (). "\u003d". session_id ());

Also, very rare, and completely incomprehensible, from where the emerging, the problem is that the session.save_handler setting has a value other than Files. If it is not so - correct.

Safety
Safety sessions - the topic is extensive. Therefore, I will stop at several main points.
The most hosted - not to transmit an identifier through address line. This is written even in php.ini, but it limits the functionality of the sessions. If you decide to follow this advice, except session.use_trans_sid \u003d 0 Do not forget to session.use_only_cookies \u003d 1
It is advisable to bind the session to the IP address: in this way, if the identifier is stolen, the villain will still not be able to use them in most cases.
It is recommended to use the session.save_path directive, with which to specify your own directory to save session files. This is more secure than when they are stored in the general temporary directory of the default server.

Additional Information:

  • In addition to Cook, the session mechanism also sends the headers that prohibit pages caching (the same Cache Limiter). For HTML it is correct and necessary. But when you are trying to give a script that verifies authorization, send the file, then the Internet Explorer refuses to download it. It is because of this header. Call
    session_cache_limiter ("Private");
    Before the start of the session should solve the problem.
  • As it seems strange, but in the array $ _Session. Cannot use numeric indexes - $ _Session [1], $ _session ["10"] - Consissions will not work.
  • Somewhere between versions 4.2 and 5.0, it was impossible to install session.use_trans_sid using ini_set () . Starting with 5.0, you can already again.
  • Prior to version 4.3.3. cook PHP. I only sent a bunch if when the session starts in the query, there was no identifier. Now the Cook is sent every time call. session_start ()

    Example of authorization using sessions
    We will illustrate everything elected by a small example:
    Create a file auth.php:
    if (ISset ($ _ post ["auth_name"]))
    {
    $ SQL \u003d. "SELECT * from Users WHERE NAME \u003d? S";
    $ row \u003d $ db -\u003e getROW ($ sql, $ _post ["auth_name"]);
    if ($ Row && Password_Verify ($ _post ["auth_pass"], $ row ["pass"])) (
    $ _Session ["user_id"] \u003d $ row ["id"];
    }
    header ("Location: http: //". $ _Server ["http_host"]. $ _Server ["Request_uri"]);
    exit;
    }

    if (ISset ($ _ get ["Action"]) and $ _get ["action"] \u003d\u003d "logout") (
    session_start ();
    session_destroy ();
    header ("Location: http: //". $ _Server ["http_host"]. "/");
    exit;
    }

    if (! isset ($ _ session ["user_id"])) (
    ?>








    exit;
    }

    Now it's enough to write in all protected scripts
    require "auth.php";
    In this example, it is assumed that the session has already started and the connection with the database is created using a class for safe and convenient work with MySQL. It is also assumed that the password is hashized using the recommended function of Password_hash.
    Example of a protected file:

    session_start ();
    include "safemysql.class.php";
    $ db \u003d new safemysql (["db" \u003d\u003e "test"]);
    include "auth.php";
    ?>
    secret.

    logout.

    OPS! Very useful links:
    http://www.php.net/manual/ru/ref.session.php is the latest and latest information on the support of sessions in PHP in official documentation, plus numerous user comments. It is strongly recommended for reading.
    http://phpclub.ru/manrus/f/ref.session.html is a very obsolete translation of this chapter into Russian, from the documentation in the translation of Alexander Pyramidin.
    http://phpclub.ru/detail/article/sessions
    Article with the pathetic title "True on sessions." Dual impression leaves. Initially, the author very affordably talks about the mechanism of sessions, but the methods that he suggests by the end of the article are completely muddy.

    CHRESTOMENT article Dmitry Borodin from the site
    http://php.spb.ru/ is urgent not recommended.
    Guys, she is terribly outdated. It is not enough that there are actual inaccuracies in it, so with sessions in PHP for a long time they simply do not work.
    Thank you so much for her, it was the first article on sessions in Russian, I myself studied on it, but now it is necessary to send it to a well-deserved rest.
    Also, outdated unfortunately, and many other articles lying on the Internet and not renewed by years.

  • Let's look at such a thing as a session (HTTP session, session). Or differently, a user session. Why it is important to understand the mechanism of work of sessions. And let's see how you can work with session states on the ASP.NET platform.

    Before we give the definition of the term "session", let's look at the prehistory a little, why did the need for sessions, consider one feature of the HTTP protocol.

    One of the main features of the HTTP protocol is that it does not oblige the server to save the client information between requests, that is, identify the client. This is the so-called stateless protocol. The relationship between the client and the server ends as soon as the processing of the current query is completed. Each new request to the server is meant as absolutely unique and independent, even if it has been sent again from the same source.

    What if you leave the statuteless nature of the HTTP protocol and do not identify the user? Without a session states, you can easily do, if your site is represented by static (dismandable) information, for example, a news article consisting of text and images. In such a context, it is absolutely optionally to associate several requests with one user. After all, the content of the article will not change in any way, whether ten requests from one device, or ten requests from different people from different devices.

    But as soon as we are going to transfer personal information to the server, we need to somehow make that the server associates all our requests from us, and in the future it defined all requests from us. If this is not done, then with each new request we will be forced to re-submit the necessary personal data. For example, login to enter personal Area On the site, or such information as a name, shipping address, when making a purchase in the online store.

    This is just in such situations when you need to personalize requests from one client, we will use sessions.

    Session (session) - This is some length in time, within which the web application can define all requests from one client.

    When a client first transmits personal data in the query, a new session is created on the server for this client. During the lifetime of the session, all requests from this client will be unambiguously recognized and associated with it. After this time, communication with the client will be lost, and the next request from it will be processed as absolutely unique, in no way associated with the previous one.

    For example, when making a purchase in the online store, the user's personal information is saved in the session while he travels through the site. These are selected products in the basket, delivery address, contact details, and so on.

    Now let's see how this we can implement technically. Generally there are several techniques for managing the sessions of the client, their number and method of implementation largely depends on the web platform or technology, which works on the server. In this lesson, we consider the following:

    1. hidden Fields on HTML (Hidden Form Fields)
    2. cookies (Cookies)
    3. session (Session, Session State)

    Let's try to implement them using the ASP.NET platform. Let's briefly consider the first two mechanisms, and special attention will be paid to the third, as a more reliable, convenient and safe.

    Hidden Fields on HTML (Hidden Form Fields)

    The essence of this approach is that we provide navigation through the site using standard HTML form. And with each next request, we keep data from the previous one in the hidden fields on the form. For example:

    @using (HTML.Beginform ("Forms2", "Home", Formmethod.post)) (

    Order dishes

    }

    Public ActionResult Forms2 () (ViewBag.UserName \u003d Request.form ["UserName"]; Return View ();)

    @using (HTML.Beginform ("Forms3", "Home", formmethod.post)) (

    @ ($ "Good afternoon (viewbag.username)! What will you order?")

    }

    In this example, we obtain the username in the first HTML form. Next in the controller in the method Forms2 () We remove this value from the collection Form and transmit to the representation through the object ViewBag.. In this view, the code is generated new form And in the hidden field, the username is saved. Thus, the value of the user name will be passed on the third shape together with for more information - field value named "FOODNAME". Etc.

    Let's consider the features of this approach. There are practically no advantages, except that this technique can be implemented very quickly. But again, other approaches can also be implemented very quickly. But there are minuses, and quite essential:


    Cookies (Cookies)

    Public ActionResult Cookies2 () (HttpCookie Cookie \u003d New HttpCookie ("UserName", httputility.urlencode (Request.form ["username"])); cookie.Expires \u003d datetime.utcnow.addhours (1); response.cookies.add ( Cookie); Return View ();)

    @using (HTML.Beginform ("Cookies3", "Home", Formmethod.post)) (

    @ ($ "Good afternoon (httputility.urldecode (Request.Cookies [" UserName "]?. Value))! What will you order?")

    }

    IN this approach We do not store session data directly on the form, instead uses the standard workbook work between the client and the server. In cookies and stored all user data.

    When this approach is selected, again, the main security problem remains the security of our data, which we pass to the server - they are easy to replace or steal, they lie in open video. Also, if the client browser privacy settings disconnected from sites from sites, this option will not work at all.

    Thus, it is extremely recommended to transmit important and secret data to the first two ways, such as logins, passwords, card numbers, accounts, passport data, place of residence, etc.

    Server Session Management Mechanism (Session, SessionState)

    We will analyze how the session mechanism works from the server side and from the client.

    For standard settings Session status operations To track a series of queries from one client is used by the so-called. Session Cookie. The algorithm is the following:

    1. Absolutely for each new request to the server (no matter, different clients or one) ASP.NET generates a unique session identifier.
      The session identifier is a randomly generated number encoded with a special algorithm in a string of a length of 24 characters. The string consists of literals from A to Z in the lower case, as well as numbers from 0 to 5. Example identifier - HJNYUIJL1PAM3VOX2H5I41IN
    2. If during the current request, the client data is not saved to further work with it, the lifetime of this client ends (actually without starting). At the same time, the previously generated session identifier becomes invalid (since it was not used). In response to such a request, the client does not get anything to associate it with a new session.
    3. If the client data (for example, the name, delivery address of the goods) is saved on the server, ASP.NET links the saved data from the previously generated session identifier. The following is a special session cookie, and this identifier is also recorded in it. This cookie is added in response to the request and saved in the client's browser. Thus, the client's connection is created and its personalized information on the server. New session for this client Created.
    4. Each time the next query, the client sends a personal session identifier to the server through cookies. The server compares the identifiers and "recognizes" the client as part of the current session.
    5. As long as the client conveys its personal key, the session is considered active. The session can end for various reasons, for example, manually on the server side or after a set time (timeout).

    From the theory, we turn to practice. Let's program this algorithm and see how it is performed. To do this, use the special HttpsessionState class. When working in the controller, you can use the httpcontext.session property. Working with the session is very simple, like with any namevaluecollection:

    Session ["UserName"] \u003d request.form ["UserName"]; BOOL ISSESSIONNEW \u003d session.isnewsession; String Sessionid \u003d session.sessional;

    In this section of the code, we write the username of the user to the session status. We take this name from the HTML form that he sent us. In addition, through the properties, we learn whether this session has just been created, that is, as part of the current request (if so, the value of the ISNewSession property will be equal to True), and the unique session identifier. This identifier after processing the query will be automatically recorded in session cookies (if not yet) and sent to the Customer response.

    In the client's browser, you can observe the appropriate cookies and the identifier of its session:

    In the process of the next query from this client, let's read its previously saved name from the session. Also forcibly completed session. Working with this client is completed, for example, all data are processed and the product is sent.

    String UserName \u003d Session ["UserName"]. Tostring (); // Request processing ... session.abandon ();

    As can be seen, working with sessions is very simple and convenient. Most processes related to the processing of the session occurs automatically in the background. Naturally, the developer may intervene at any stage of the session processing and make its adjustments.

    Let's look at the most interesting properties and methods of Httpsessionstate class, which are most often used in the work:

    Item. - Returns the data item on its index
    Item. - Returns the data element by its key
    REMOVE (INDEX) - deletes the data item on its index
    REMOVE (KEY) - removes the data element by its key
    Clear () - Deletes all data
    Count - Returns the total number of data items for the current session.
    Abandon () - forcibly complete the session
    Sessionid - Returns the current session identifier
    IsnewSession. - Returns TRUE if the session was created as part of the current request
    Timeout. - Returns the number of minutes allowed between requests before the session will be completed due to the timeout (default, 20 minutes)

    You can change the settings for the session either programmatically in code via HttpsessionState class members or through an application configuration (). For example:

    In the configuration above, we indicated that the sessions timeout will be 40 minutes, the user's session data will be stored in random access memorySession cookies will be used, also changed the standard name of such cookies on their own.

    And one more important safety remark. When you complete the session of the user by Session.abandon (); Sessionid session cooking identifier, is not deleted in the user's browser. This means that if the user starts a new session in the near future, without closing the browser, then his new session will be assigned the same sessionid. Preferably each new session always assign a new unique identifier, for this we need to manually delete session cookies after closing the session:

    Session.clear (); // Clean the session.abandon () session; // We cancel the session // manually clean the cookies like the resultse.cookies.add (new httpcookie ("ASP.NET_SESSIONID", "")); // or reduce the lifetime of response.cookies ["ASP.NET_SESSIONID"]. Expires \u003d datetime.now.addyears (-30); //Asp.net_sessionid is the standard name of session cookies, you can have your own

    In this way, tracking the status of the user session on the ASP.NET platform, using sessions. This approach is standard and is recommended for use when you need to save the user information and identify it between the requests to the server.

    Greetings, respected community.

    First of all, I want to thank for a very useful resource. More than once found many interesting ideas and practical advice here.

    The purpose of this article is to highlight the underwater stones of the use of sessions in PHP. Of course, there is a documentation on PHP and a lot of examples, and this article does not pretend to full guide. She is designed to reveal some nuances of work with sessions and protect developers from unnecessary spending time.

    The most common example of using sessions is, of course, user authorization. Let's start with the most basic implementation in order to consistently develop it as new tasks appear.

    (In order to save space and time, it is limited to the examples only by the functions of working with sessions, instead of building a full-fledged test application with a beautiful hierarchy of classes, comprehensive error processing and other correct things).

    Function StartSession () (// If the session has already been running, stop execution and return True // (Session.Auto_start parameter in the PHP.ini settings file must be turned off - the default value) if (session_id ()) Return True; Else Return Session_start (); // Note: To version 5.3.0, the session_start () function returned true even in case of an error. // If you are using a version below 5.3.0, perform additional session_id check () // after calling session_start ()) FUNCTION DestroySession () (if (session_id ()) (// if there is an active session, remove cookies session, setcookie (session_name (), session_id (), time () - 60 * 60 * 24); // and destroy session_unset session ( ); session_destroy ();))

    Note: It is understood that the basic knowledge of PHP sessions at the reader has, therefore the principle of operation of the SESSION_START () and session_destroy () functions will not cover here. The tasks of the layout form and user authentication form do not refer to the topic of the article, so we will also omit them. Let me remind you only that to identify the user in each subsequent request, we need to be saved at the time of successful input in the session variable (with the userid name, for example) the user ID, which will be available in all subsequent requests within the session's life. It is also necessary to implement the processing of the result of our StartSession () function. If the function has returned FALSE - to display the input shape in the browser. If the function has returned True, and the session variable containing an authorized user identifier (in our case - UserID), exists - to display a page of an authorized user (for more on error processing, see Appendix from 2013-06-07 in the section on session variables).

    While everything is clear. Questions begin when it is required to implement the absence of user activity (Session Timeout), enable simultaneous work in one browser of several users, as well as protect sessions from unauthorized use. This will be discussed below.

    Control of the lack of user activity with built-in PHP

    The first question, which often arises from the developers of all sorts of consoles for users - the automatic completion of the session in the absence of activity from the user. There is nothing easier than to do it using the built-in PHP features. (This option does not differ in particular reliability and flexibility, but consider it for completeness of the picture).

    Function StartSession () (// Timeout lack of user activity (in seconds) $ SessionLifetime \u003d 300; if (session_id ()) Return True; // Set the life of the Cookie ini_set ("session.cookie_lifetime", $ sessionlifetime); // if Timeout lack of user activity set, set the life of the session on the server // Note: For the product server, it is recommended to prevent these parameters in the PHP.ini if \u200b\u200b("SessionLifetime) ini_set (" session.gc_maxlifetime ", $ sessionlifetime); if (session_start ( )) (SETCOOKIE (session_name (), session_id (), time () + $ sessionlifetime); Return True;) Else Return False;)

    Some explanations. As you know, PHP determines which one session you need to run, by the name of Cook, transmitted by the browser in the request header. The browser, in turn, receives this cookie from the server where its session_start () function places. If the lifetime of cookies in the browser has expired, it will not be transferred in the query, which means PHP will not be able to determine which session should be launched, and it is consistent as creating a new session. Parameter pHP settings session.gc_maxlifetime, which is set to our timeout of the lack of user activity, sets the lifetime of the PHP session and is controlled by the server. It works control of the life of the session as follows (there is an example of a session storage in temporary files as the most common and default option in the PHP).

    At the time of creating a new session in the directory installed as a directory for storing sessions in the PHP session.save_path settings parameter, the file named sess_ is created. where - session identifier. Further, in each request, at the time of launching the already existing session, PHP updates the modification time of this file. Thus, in each next PHP query, by difference between the current time and the time of the last modification of the session file, can determine whether the session is active, or its lifetime has already expired. (The removal mechanism of old session files is considered in more detail in the next section).

    Note: It should be noted here that the session.gc_maxlifetime parameter is valid for all sessions within one server (more precisely, within one main pHP process). In practice, this means that if there are several sites on the server, and each of them has its own timeout of the lack of user activity, then installing this parameter on one of the sites will be installed and for other sites. The same applies to the shared hosting. To avoid such a situation, separate session directories are used for each site within a single server. Setting the path to the session catalog is made using the session.save_path parameter in the php.ini settings file, or by calling the INI_SET () function. After this session of each site will be stored in separate directories, and the session.gc_maxlifetime parameter installed on one of the sites will only be valid at its session. We will not consider this case in detail, especially since we have a more flexible version of the absence of user activity.

    Control of the lack of user activity using session variables

    It would seem, the previous option with all its simplicity (just a couple of additional lines of code) gives everything we need. But what if not every request can be regarded as a result of user activity? For example, a timer is set on the page, which periodically executes the Ajax request to receive updates from the server. Such a request cannot be regarded as user activity, which means the automatic extension of the lifetime of the session is not correct in this case. But we know that PHP updates the session file modification time automatically each time the session_start () function is called, which means any request will lead to the extension of the life time of the session, and the lack of user activity will never come. In addition, the last note from the previous section on the intricacies of the SESSION.GC_MAXLIFETIME parameter may appear to someone too confusing and complex in the implementation.

    To solve this problem, we will refuse to use the built-in pHP mechanisms And we introduce several new session variables that will allow us to control the lack of user activity yourself.

    Function StartSession ($ iSessionLifetime \u003d True) ($ sessionlifetime \u003d 300; if (session_id ()) Return True; // Install Cook's Lifetime before closing the browser (you will control everything on the server side) ini_set ("session.cookie_lifetime", 0) ; if (! session_start ()) Return False; $ T \u003d Time (); if ($ sessionlifetime) (// If the lack of user activity is specified, // check the time that has passed since the last user activity // (the last query time When the LastActivity session variable was updated) if (ISSET ($ _ session ["LastActivity"]) && $ T - $ _ session ["LastActivity"]\u003e \u003d $ SessionLifetime) (// If the time passed since the last user activity, / / More timeout lack of activity, which means the session has expired, and you need to complete the DESTROYSESSION (); RETURN FALSE;) Else (// if the timeout has not yet come, // and if the query came as the result of the user's activity, // Update the variable LastActivity Current BP Emeni, // extending the time of the session is still on sessionlifetime seconds if ($ iSuseractivity) $ _session ["LastActivity"] \u003d $ t; )) Return True; )

    Summarize. In each request, we check whether the timeout will be reached from the moment of the last user activity before the current moment, and if it is achieved - we destroy the session and interrupt the function, returning False. If the timeout is not achieved, and the $ iSuseRactivity parameter with the value of True - update the time of the user's last activity. All that we have to do is to determine in the calling script whether the request is the result of the user's activity, and if not, call the StartSession function with the value of the $ iSuseRactivity parameter equal to FALSE.

    Update from 2013-06-07
    Processing the result of the SessionStart () function

    The comments did not pay attention to the fact that False's refund does not fully understand the cause of the error, and it is absolutely fair. I did not publish here a detailed processing of errors (the scope of the article and is not small), as this does not apply directly to the topic of the article. But considering comments, I will clarify.

    As you can see, the SessionStart function can return False in two cases. Or the session could not be launched due to some internal server errors (for example, incorrect session settings in php.ini), or the session lifetime expired. In the first case, we must transfer the user to the page with an error that there are problems on the server, and the form of handling support. In the second case, we must translate the user to the input form and bring the appropriate message to it that the session time has expired. To do this, we need to enter error codes and return the corresponding code instead of FALSE, and in the calling method, check it and act accordingly.

    Now, even if the session on the server still exists, it will be destroyed at the first appeal to it if the timeout of the lack of user activity has expired. And this will happen regardless of what time the sessions are installed in the global PHP settings.

    Note: What happens if the browser was closed, and cookies with the session name was automatically destroyed? The request to the server, the next time you open the browser, will not contain cookies session, and the server will not be able to open the session and check the lack of user activity. For us, it is equivalent to creating a new session and does not affect the functionality and safety. But there is a fair question - and who will then destroy the old session, if we still destroyed it after the expiration of Taimaut? Or will she now hang in the sessions catalog forever? To clean the old sessions in PHP, there is a mechanism called Garbage Collection. It starts at the time of the next request to the server and cleans all the old sessions on the basis of the date last change Session files. But the start of the Garbage Collection mechanism does not occur at each request to the server. The frequency (or rather, the probability) of startup is determined by two parameters of the session.gc_probability and session.gc_divisor settings. The result from the division of the first parameter to the second and is the probability of launching the Garbage Collection mechanism. Thus, so that the sessions cleaning mechanism be launched with each request to Severor, these parameters need to be set to equal values, for example "1". This approach guarantees the purity of the session directory, but obviously is too overlaid for the server. Therefore, in the default product systems, the session.gc_divisor value is set, equal to 1000, which means that the Garbage Collection mechanism will be launched with a probability of 1/1000. If you experiment with these settings in your php.ini file, you can notice that in the case described above, when the browser closes and clears all your cookies, in the session catalog, for some time old sessions are still. But it should not worry you, because As already mentioned, it does not in any way affect the safety of our mechanism.

    Update from 2013-06-07

    Prevent script hangs due to session file blocking

    In the comments raised the question of hanging simultaneously running scripts due to blocking the session file (as the brightest option - Long Poll).

    To begin, I note that this problem does not directly depend on the server load or the number of users. Of course, the more requests, the slower the scripts are performed. But this is a cosquid dependence. The problem appears only within the same session when the server comes several requests on behalf of one user (for example, one of them is LONG POLL, and the rest are normal requests). Each request is trying to access the same session file, and if the previous query has not unlocked the file, then the next will hang out waiting.

    To close the session files to minimize, it is strongly recommended to close the session by calling the session_write_close () function immediately after all actions with sessive variables are performed. In practice, this means that it should not be stored in session variables in a row and contact them throughout the execution of the script. And if you need to store some working data in session variables, you immediately read them at once when you start the session, save to local variables for subsequent use and close the session (it means closing the session using the session_write_close function, and not destruction using session_destroy).

    In our example, this means that immediately after opening the session, checking the time of its life and existence of an authorized user, we must read and save all the additional applications to the session variables (if there are such), after which it is close to the session by calling session_write_close () and continue Execution of the script, whether Long Poll or a regular query.

    Protection of sessions from unauthorized use

    Imagine the situation. One of your users clins Troyan, who robs the bouquet of the browser (in which our session is stored) and sends it to the specified email. The attacker gets cookies and uses it for a fake query on behalf of our authorized user. The server successfully accepts and processes this request, as if it came from an authorized user. If an additional IP address check is implemented, such an attack will lead to a successful hacking user account with all the ensuing consequences.

    Why was it possible? Obviously, because the name and identifier of the session are always the same at the same time of the session, and if you get this data, you can easily send requests on behalf of another user (naturally, within the lifetime of this session). Perhaps this is not the most common type of attacks, but theoretically, everything looks quite realizable, especially considering that the administrator rights do not even need such a trojan to rob the user browser cookies.

    How can I protect against attacks of this kind? Again, obviously, limiting the lifetime of the session identifier and periodically changing the identifier within one session. We can also change the session name, completely removing the old and creating a new session by copying all session variables from the old one. But it does not affect the essence of the approach, therefore, for simplicity, it is limited to the identifier of the session.

    It is clear that the smaller the lifetime of the session identifier, the less time will be at the attacker to get and apply cookies for fake user request. In the perfect case, a new identifier must be used for each request, which will allow you to minimize the possibility of using someone else's session. But we consider the general case when the session identifier regeneration time is set arbitrarily.

    (Lower the part of the code that has already been considered).

    Function StartSession ($ iSuseRACTIVITY \u003d TRUE) (// Life time of the identifier of the session $ idlifetime \u003d 60; ... if ($ idlifetime) (// If the lifetime of the session identifier is set, // Check the time that has passed since the session or the last session Regeneration // (the last query time when the session variable starttime was updated) if (ISSET ($ _ session ["starttime"])) (if ($ T - $ _ session ["starttime"]\u003e \u003d $ idlifetime) (// Time Lifestyle session identifier // Generate a new session_regenerate_id identifier (true); $ _session ["starttime"] \u003d $ t;)) Else (// Here we get if the session has just been created // Set the session identifier generation time at the current time $ _Session ["starttime"] \u003d $ t;)) Return True;)

    So, when creating a new session (which occurs at the time of successful user login), we set the STARTTIME session variable stored for us the last generation of the session identifier, to the value equal to the server time. Next, in each request, we check whether enough time (IDLIFETIME) has not passed since the last generation of the identifier, and if it passed - we generate a new one. Thus, if an attacker who received cookies of an authorized user who received the identifier of the identifier of the identifier does not have time to use it, the fake request will be regarded by the server as an unauthorized, and the attacker will fall on the entry page.

    Note: The new session identifier enters the browser cookies when calling the session_regenerate_id () function (), which sends new cookies, similar to the session_start () function, so we do not need to update cookies yourself.

    If we want to secure our sessions as much as possible, it is enough to establish the identifier's lifetime lifetime or generally to endure the session_regenerate_id () function for brackets and remove all checks, which will lead to the identifier regeneration in each request. (I did not check the impact of such a speed approach, and I can only say that the session_regenerate_id (true) function performs essentially 4 steps: generating a new identifier, creating a header with Cook session, delete the old and creating a new session file).

    Lyrical digression: If Troyans turns out to be so smart that it will not send Cookies to an attacker, and he organizes the sending of a predetermined fake request immediately upon receipt of Cook, the method described above, most likely, will not be able to protect against such an attack, because between the time of receiving Trojan cookies and sending fake The query will almost not be difference, and the likelihood is great that at this point will not receive the regeneration of the session identifier.

    The ability to simultaneously work in one browser on behalf of several users

    The last task that I would like to consider is the possibility of simultaneous work in one browser of several users. This feature is especially useful at the test stage when you need to emulate the simultaneous operation of users, and it is advisable to do this in your favorite browser, and not use the entire available arsenal or open several instances of the browser in the "incognito" mode.

    In our previous examples, we did not define the name of the session, so the default name set in PHP is used. This means that all sessions that have been created by us so far have sent Cook browser under the name PHPSESSID. Obviously, if the cooking name is always the same, then there is no possibility within one browser to organize two sessions with the same name. But if we used our own session name for each user, the problem would be solved. And do it.

    Function StartSession ($ IsuseRactivity \u003d True, $ prefix \u003d null) (... if (session_id ()) Return True; // If the parameters pass the user prefix, // Set the unique session name, including this prefix, // otherwise install General for all users Name (for example, MyProject) Session_name ("MyProject". ($ prefix? "_." $ prefix: "")); ini_set ("session.cookie_lifetime", 0); if (! session_start ()) RETURN FALSE; ...)

    Now it remains to take care that the calling script transmit to the StartSession () function is a unique prefix for each user. This can be done, for example, through the transfix to the GET / POST parameters of each request or through additional cookies.

    Conclusion

    In conclusion, I will give the full end code of our functions to work with sessions php.which includes all the tasks discussed above.

    Function StartSession ($ iSuseractivity \u003d True, $ prefix \u003d null) ($ sessionlifetime \u003d 300; $ idlifetime \u003d 60; if (session_id ()) Return True; session_name ("MyProject". ($ Prefix? "_". $ Prefix: "" ")); ini_set (" session.cookie_lifetime ", 0); if (! session_start ()) Return false; $ t \u003d time (); if ($ sessionlifetime) (IF (ISSET ($ _ session [" LastActivity "] ) && $ T - $ _ session ["LastActivity"]\u003e \u003d $ sessionlifetime) (destroysession (); Return False;) ELSE (if ($ iSuseRActivity) $ _session ["LastActivity"] \u003d $ t;)) if ($ idlifetime ) (IF (ISSET ($ _ session ["starttime"])) (if ($ T - $ _ session ["starttime"]\u003e \u003d $ idlifetime) (session_regenerate_id (true); $ _session ["starttime"] \u003d $ t; )) ELSE ($ _session ["starttime"] \u003d $ t;)) Return True;) FUNCTION DESTROYSESSION () (if_unset (); setcookie (session_name (), session_id (), time () -60 * 60 * 24); session_destroy ();))

    I hope that this article will save some time to those who have never really deepened into the session mechanism, and will give enough understanding of this mechanism to those who are just starting to get acquainted with PHP.

    In module Active Cessia You can see a list of users working with the control panel at any time. this momentThe IP address from which the user accesses and the time passed from the moment the last command is received from this user.

    If necessary, you can complete the session of the selected user.

    Module "Active sessions"

    View current connections information

    • Session ID - A unique number identifying a session with the control panel. By default, the information is displayed in the table for 60 minutes.
    • User - The user name connected to the system is currently.
    • Access - Access level of this user to the control panel (for example, superuser, server administrator, user, etc.).
    • IP address - A remote IP address from which access is available.
    • Expectation - The time passed from the moment the control panel received the last command from the user.
    • Active requests - Number of active requests.

    Completion of the session

    To complete this or that session with the control panel, highlight the required rows in the list of active sessions and click Finish.

    To prevent accidental delets, the control panel will ask you to confirm or cancel your action. If you click "OK" in the Confirmation window, then the selected sessions will be completed.

    If the session was completed, for further work with the control panel, the user must log in again.

    This form is not an appeal to support.
    We can not identify you and answer your message.

    Session (from Lat. - Sessio - meeting, English - Session) - This is a period of time covering the user on the Internet from the moment of opening the first and to the last links. It is calculated as the time difference between the initial and final requests. However, the last page can be viewed by the user in different times, from which, therefore, the time measurement between two requests becomes more difficult.

    How is the session with the HTTP and Cookies Protocol

    What such a session can be explained by pushing out from the HTTP protocol. By itself, this protocol does not have a way to preserve the state between two operations. Those., Simply put, opening one page, and then, going from it to another, HTTP will not be able to establish that both requests belong to one user. And here the help of a special tracking method comes to the help - control of sessions (by our sessions).
    From here, answering the question what kind of session, we can say that this is an auxiliary logical object that promotes data transmission between sequential HTTP requests from one user.
    Cookies, like the session, store information about the user during its move on different pages and improve the operation of the protocol. But unlike the second, where data is stored in temporary files on the server, they store them on a user's computer in the form of small fragments.

    For what sessions need

    The use of sessions becomes indispensable when working with such sites as forums, bulletin boards and online stores, because in this case you need to save user data for several pages.

    Stages of the session

    All session can be divided into three stages:

    • opening session (when the user starts working with a specific site),
    • accounting for variable sessions (when moving to various pages),
    • completion of the session.

    Due to the fact that these sessions are stored on a third-party server, it is best not to keep large amounts of information in them, but to use cookies.