Borovsky index php user. PHP network defense techniques

SuperGlobal $ _Server array

One of the most important predefined arrays is an $ _Server array - a PHP interpreter places variables received from the server. Without these variables, it is difficult to organize full support for Web applications. The following is a description of the most important elements of the superglobal array $ _Server.

Comment

View a complete list of an array of $ _Server array can be either using the print_r () function, which prints the dump of the array or using the PHPInfo () function, which displays information about the PHP interpreter.

Element $ _Server ["document_root"]

The $ _Server element ["document_root"] contains the path to the server's root directory if the script is performed in the virtual host, this element indicates the path to the root directory of the virtual host. Those. In the configuration file httpd.conf, the virtual host has a DocumentRoot directive, which is assigned the value "D: / MAIN", the $ _Server element ["Document_Root"] will contain the value "D: MAIN".

Element $ _Server ["http_accept"]

The $ _Server element ["http_accept"] describes the client preferences relative to the type of document. The contents of this element is removed from the HTTP header of the Accept, which sends the client to the server. The contents of this title may look as follows.

image / Gif, Image / X-XBitmap, Image / Jpeg, Image / Pjpeg, Application / X-Shockwave-Flash, Application / VND.MS-Excel, Application / MSWORD, * / *

The ACCEPT header allows you to clarify the media type that prefers to get the client in response to your request. This title allows you to tell the server that the answer is limited by a small set of preferred types.

The * symbol is used to group types in the media row. For example, the * / * symbol is set to use all types, and the Type / * designation determines the use of all subtypes of the selected type type.

Comment

Media types are separated from each other commas.

Each media series is also characterized by an additional set of parameters. One of these is the so-called relative preference coefficient Q, which takes values \u200b\u200bfrom 0 to 1, respectively, from less preferred types to more preferred. The use of several parameters Q allows the client to inform the server with a relative degree of preference for a particular media type.

Comment

By default, the parameter q takes a value 1. In addition, from the media-type it is separated by a semicolon.

An example of a header type Accept:

ACCEPT: Audio / *; Q \u003d 0.2, Audio / Basic

In this title, the first type AUDIO / * includes all the music documents and characterized by the preference ratio of 0.2. Through the comma, the type of Audio / Basic is specified, for which the preference coefficient is not specified and the default value is equal to one. By quoting RFS2616 This title can be interpreted as follows: "I prefer the type of Audio / Basic, but I can also send documents of any other Audio-type if they are available, after reducing the preference coefficient by more than 80%."

An example may be more complicated.

Accept: Text / Plain; q \u003d 0.5, Text / HTML,
Text / X-DVI; Q \u003d 0.8, Text / X-C

Comment

It should be borne in mind that the $ _Server [HTTP_ACCEPT] element contains exactly the same information, but without the initial accept header.

This header is interpreted as follows: Types of Text / HTML and Text / XC documents are preferred, but if they are not available, then the client sending this request will prefer the text / x-dvi, and if it is not, then it can take Type Text / Plain.

Element $ _Server ["http_accept_language"]

The $ _Server element ["http_accept_language"] describes the client preferences relative to the language. This information is extracted from the ACCEPT-Language HTTP header, which sends the client to the server. You can give the following example:

Accept-Language: RU, EN; Q \u003d 0.7.

Which can be interpreted as follows: the client prefers Russian, but in the case of its absence I agree to accept documents in English. An element $ _Server ["http_accept_language"] will contain exactly the same information, but without the ACCEPT-Language header:

rU, EN; Q \u003d 0.7.

The contents of the $ _Server element ["http_accept_language"] can be used to determine the national affiliation of visitors. However, the results will be approximate because many users use English browser versions that will notify the server that the visitor prefers only one language - English.

Element $ _Server ["http_host"]

The $ _Server element ["http_host"] contains a server name, which, as a rule, coincides with the domain name of the site located on the server. As a rule, the name specified in this parameter coincides with the name $ _Server ["Server_Name"]. The parameter provides only a domain name without the protocol name (http: //), i.e.

www.sofftime.ru.

Element $ _Server ["http_referer"]

The $ _Server element ["http_referer"] is given a page address with which the visitor came to this page. The transition must be exercised by reference. Create two index.php and page.php pages.

Page index.php.

echo. "Link to PHP page
"
;
Echo.
$ _Server ["http_referer"]
?>

Page.php page will be similar content, but the link will indicate the index.php page.

Page. Page.php.

echo. "Link to PHP page
"
;
Echo. "CONTENT $ _SERVER [" http_referer "] -".
$ _Server ["http_referer"]
?>

When you go from one page to another, the address of the page will be displayed with which the transition was carried out.

Element $ _Server ["http_user_agent"]

The $ _Server ["http_user_agent"] element contains information about the type and version of the browser and the visitor operating system.

Here is the typical content of this string: "Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1)". The presence of a substring "MSIE 6.0" suggests that the visitor browsing the page using Internet Explorer version 6.0. The "Windows NT 5.1" row reports that Windows XP is used as the operating system.

Comment

For Windows 2000, the $ _SERVER ["http_user_agent"] element looks like this: "Mozilla / 4.0 (compatible; MSIE 5.01; Windows NT 5.0)") ", while for Windows XP -" Mozilla / 4.0 (compatible; MSIE 6.0 ; Windows NT 5.1) ".

If the visitor comes with the Opera browser, then the content of $ _Server ["http_user_agent"] may look like this: "Mozilla / 4.0 (compatible; MSIE 5.0; Windows 98) Opera 6.04". MSIE 6.0 substring here is also present, reporting that the Opera browser is compatible with the Internet Explorer browser and uses the same Windows dynamic libraries. Therefore, when analyzing a row returned by the browser, it should be borne in mind that the Internet Explorer includes a string containing the MSIE 6.0 substitute and does not contain the "Opera" substring. In addition, from this line, it can be concluded that the user uses the Windows 98 operating system.

Comment

The Firefox browser user agent may look as follows Mozilla / 5.0 (Windows; U; Windows NT 5.1; EN-US; RV: 1.8) GECKO / 20051111 Firefox / 1.5.

When using the NetScape browser, the content of the $ _Server ["http_user_agent"] element may look as follows: "Mozilla / 5.0 (x11; U; Linux i686; EN-US; RV: 1.4) GECKO / 20030624 NETSCAPE / 7.1". Belonging to this browser can be determined by the presence of a substring "NetScape". In addition, you can find out that the visitor goes into the Internet using the operating version of Linux, with a kernel optimized for Pentium IV, while in the X-Window graphics shell. This mechanism is convenient to use to collect statistical information, which allows designers to optimize pages for the most common browsers.

Element $ _Server ["Remote_ADDR"]

The IP address of the client is placed in the $ _Server ["Remote_ADDR"] element. When testing on a local machine - this address will be equal to 127.0.0.1. However, when testing on the network, the variable will return the client's IP address or the last proxy server through which the client hit the server. If the client uses the proxy server to learn its IP address using the HTTP_X_Forwarded_For environment variable, the value of which can be obtained using the GETENV () function.

Comment

Proxy servers are special intermediate servers providing a special type of service: compression of traffic, data encoding, adaptation under mobile devices, etc. Among the multiple proxy servers distinguish the so-called anonymous proxy servers that allow you to hide the true IP address of the client, such servers do not return the HTTP_X_Forwarded_FOR environment variable.

Removing the HTTP_X_Forwarded_For environment variable

eCHO GETENV (http_x_forwarded_for);
?>

Element $ _Server ["script_filename"]

The $ _Server element ["script_filename"] is placed an absolute path to the file from the root of the disk. So, if the server runs running the Windows operating system, then this path may look like this "D: Main Estindex.php", i.e. The path is specified from the disk, in a UNIX-like operating system, the path is indicated from the root directory /, for example, "/Var/Share/www/Test/index.php".

Element $ _Server ["Server_Name"]

In the $ _Server ["Server_name"] element, the server name is placed, as a rule, coinciding with the domain name of the site located on it. For example,

www.softtime.ru.

The contents of the $ _Server element ["Server_name"] often coincides with the content of the $ _Server element ["http_host"]. In addition to the server name, the superglobal array of $ _Server allows you to find out another number of server parameters, such as the IP address of the server, listening to the port, which WEB server is installed and the version of the HTTP protocol. This information is placed in the $ _Server ["Server_addr"], $ _Server ["Server_Port"], $ _Server ["Server_Software"] and $ _Server ["Server_protocol"], respectively. The following is an example using data items.

Using an array elements $ _Server

echo "Server Name -". $ _Server ["Server_Name"]. "
" ;
Echo. "Server IP address". $ _Server ["Server_addr"]. "
" ;
Echo "Port Server -". $ _Server ["Server_PORT"]. "
" ;
Echo "Web server -". $ _SERVER ["Server_Software"]. "
" ;
Echo. "HTTP protocol version -". $ _Server ["Server_protocol"]. "
" ;
?>

Element $ _Server ["Request_Method"]

The $ _Server [Request_Method] element is placed in the query method, which is used to call the script: Get or Post.

From the very beginning, PHP accepted everything with a bang, but as soon as there were quite large projects in this language, the developers faced a new problem - there was no concept of global variables in PHP! That is, a certain script was performed, sent a generated page to the client, and all the resources used by this script were destroyed. I will try to illustrate: Suppose there are two pages of one site, index.php and dothings.php. The source code to these pages look like this:

index.php. dothings.php.

If you perform these two scripts, then on the first page we will see the inscription "I was set on index.php", and the second page will be empty.

Web site developers, not thinking, began to use cookies to store global variables on the client side. The process looked something like this: the user comes to the main page of the site, makes some actions, and all information related to this user who may be required on other pages of the site will be stored in his browser in the form of a cookie. This method has quite serious minuses, because of which many developers turned away from PHP at one time. For example, we need to authorize the user to allow it to access the sections of the site closed (or belonging to it). You will have to send a cookie to the user who will serve its subsequent identifier on the site. This approach becomes very cumbersome and not convenient as soon as the site begins to collect more and more information about the user's behavior, because all the information sent to the user is desirable to encode so that it cannot be faked. More recently, the cookie could be "put" not one chat, but sometimes get into someone else's mail. In addition, there are still strange people in the world whose cookie browser does not support.

I will not go into technological issues of the device of the mechanism of work of the sessions, but only I will describe how to work correctly with sessions in PHP.

How to work with sessions?

If you test examples from the article (or your scripts) on any commercial hosting, there should be no problems with work with sessions. If you yourself configured your server (whether it is a real server, or an emulator), an error may appear about such a content:

"Warning: Open (/ var / state / PHP / SESS_6F71D1DBBB52FA88481E752AF7F384DB0, O_RDWR) Failed: No Such File or Directory (2)".

This means just that you are incorrectly configured PHP. You can solve this problem by speaking the correct path (on the existing directory) to save sessions in the php.ini file and restart the server.

Any script that will use variables (data) from sessions must contain the following line:

Session_start ();

This command tells the server that this page needs all variables that are related to this user (browser). The server takes these variables from the file and makes them available. It is very important to open the session before any data will be sent to the user; In practice, this means that the session_start () function is desirable to call at the very beginning of the page, for example:

Session_start (); ?\u003e ... To set the directory in which the session files will be saved using the session_save_path () function: session_save_path ($ _ server ["document_root"]. "/ Session"); session_start ();

After the start of the session, you can set global variables. Ari assigning any value to any field of an array $ _session, the variable with the same name is automatically registered as a variable session. This array is available on all pages using the session. For example, we will analyze the program:

index.php. All OK. Session uploaded! Let's go, let's see what: dothings.php.

With consistent starts of these files, the first "index.php" script will display the following result:

All OK. Session uploaded! Let's go, let's see what:

And the second "dothings.php" is this:

I was asked on index.php

The $ A variable is now available on all pages of this site that launched sessions.

Other useful features and techniques for working with sessions:

  • unset ($ _ session ["a"]) - the session "forgets" the value of a given session variable;
  • session_destroy () - the session is destroyed (for example, if the user left the system by clicking the "output" button);
  • session_set_cookie_params (int lifetime [, String Path [, String Domain]]) - With this feature, you can install how long the session will be "live" by setting the UNIX_TIMESTAMP the decisive time of the "death" of the session. By default, the session "lives" until the client closes the browser window.
  • session_write_close () - Recording seiani variables and closing it. This is necessary to open the site in a new window if the page performs long-lasting processing and blocked for your browser session file.

Examples

Now we turn to the practical application of the session mechanism. Here we will look at a couple of pretty simple and at the same time useful examples.

User authorization

Questions on user authorization using PHP sessions are constantly set in conferences on Web programming. The mechanism of user authorization in the system using sessions is quite good in terms of safety (see Section).

Our example will consist of three files: index.php, authorize.php and secretplace.php. The index.php file contains a form where the user enters its username and password. This form will transfer data to the authorize.php file, which in case of successful authorization will allow the user to the SecretPlace.php file, and otherwise the error message will display.

Examples: index.php. Enter the password

Login:
Password:
authorize.php. page ... Header ("Location: SecretPlace.php"); exit; )) // If something was wrong, the user will receive // \u200b\u200berror message. ?\u003e You entered the wrong password! secretplace.php. Hello,, you're on the secret page !!! :)

Security

So, we can transfer the identifier from one page (PHP script) to another (until the next call from our site), which means we can distinguish all site visitors. Since the session identifier is a very large number (128 bits), the chances that it will be possible to choose a bust, practically no. Therefore, the attacker remains the following possibilities:

  • on a user's computer is "Troyan", which steals session numbers;
  • the attacker caught the traffic between the user and the server. Of course, there is a protected (encrypted) SSL protocol, but they do not use everything;
  • a neighbor approached the computer of our user and pulled the session number.

Such situations based on the fact that someone will make something in someone, generally, are not included in the competence of a programmer. This should take care of administrators and ourselves.

However, PHP is very often able to "fool." Let's look at the possible hacking points in the user authorization program:

  • File authorize.php - an attempt to select a password using a third-party script;
  • The SecretPlace.php file is an attempt to deceive the program by entering the values \u200b\u200bof the $ Logged_user variable in the browser address bar, for example, as follows:
    "http://www.yoursite.ru/secretplace.php? logged_user \u003d hacker"

So, in our program, two "holes" are clearly visible, one small and not particularly noticeable, but the second is just a huge, through which most hackers and climbs where it is not necessary.

How to "patch up" hole number 1?

We will not write tons of code to block the IP address, etc., but simply check where the query comes from, or rather from which page a request came, if it is any page from our site, then everything is fine, but in all other cases Let's not let. Correct the file authorize.php:

authorize.php v2. page ... Header ("Location: SecretPlace.php"); exit; )))?\u003e You entered the wrong password!
How to get rid of "hole" number 2?

Suppose you have a website where every mortal can register to add messages to the forum. Naturally, in the forum in some users (admins, moderators), there are more opportunities than others, they, for example, can delete messages of other users. The user access level you store in the session, in the $ user_status variable, where $ user_status \u003d 10 matches full access to the system. An attacker who came to the site is enough to register with the standard way, and then add in the address bar of the browser ? user_status \u003d 10. So got on your forum new admin!

In principle, any variable of the script can be set via the address bar by simply adding the question mark after the full address to the script and the name of the variable with its value. Let's replant our code to avoid this:

secretPlace.php v2. Unset variable ($ _ session ["Logged_user"]); // Open session_start () session; / * Just go to this page can not ... if the username is not registered, then redirect it to the index.php page to enter the login and password ... Here you can actually do a lot of things, for example, to remember the IP of the user, and after the third Attempts to access files, overlap it. * / if (! isset ($ _ session ["Logged_user"])) (header ("Location: index.php"); exit;)?\u003e Hello,, You are on the secret page! RESULTS

The session mechanism is a rather successful feature of the PHP language. Sessions are simple, very flexible to use. By the way, there is one, little where the documented possibility of PHP sessions (is available from version 4.0.3) - in sessions you can store not only variables, but also objects.

Examples

?>
// Automatic SID insertion in reference. INI_SET ("session.use_trans_sid", True); session_start (); ?\u003e CLICK HERE!
Click Here !!

// Sample working with sessions. session_start (); // If only came to the site, reset the counter. if (! isset ($ _ session ["count"])) $ _session ["Count"] \u003d 0; // Increase the counter in the session. $ _Session ["Count"] \u003d $ _session ["Count"] + 1; ?\u003e

Counter

Once (a).
Close the browser to reset the counter.
"target \u003d" _ blank "\u003e Open a browser's subsidiary.
// A simple example of using sessions without cookies. session_name ("test"); session_start (); $ _Session ["Count"] \u003d @ $ _ session ["count"] + 1; ?\u003e

Counter

In the current work session with the browser, you opened this page. Once (a).
Close the browser to reset this meter.
?"\u003e Click here to update the page!

The component serves to output the authorization form. Used usually in the site design template. The component is standard and enters the module distribution. In the visual editor, the component is located on the way: Service\u003e User..

In the visual editor, the component is located on the way: Service\u003e User\u003e Authorization Form.

An example of calling component system.Auth.form.

Description of parameters

Password recovery mechanism (for reference)

If the user requested the password recovery, the recovery occurs according to the following mechanism:

  1. The user clicks on Forgot your password? in the form of authorization.
  2. A random string is generated 32 characters long, taking into account the secret, known only to the server.
  3. The result is written in the database and sent to the mail. Link type: http://site.ru/bitrix/admin/index.php?change_password\u003dyes&lang\u003dru&user_checkword\u003d3farde09fay52547f11c68bf17d95760&user_login\u003dmarket.Where:
    • http://site.ru/bitrix/Admin/index.php - path to the login page or change password;
    • change_Password \u003d YES - password change action;
    • lang \u003d ru Identifier language;
    • USER_CHECKWORD \u003d - control string to change the password 32 symbol. The string uses characters. Available to MD5 :.

      When you change the password in the query of the control line, you only enter a test string, without user_checkword \u003d!

    • & User_login \u003d market - Specifying for which user a password is shown.
  4. When comparing the test line from the form with what is recorded in the database, the expiration time specified in the Group's Group Policy is taken into account.

Note. In the form of password recovery, it is recommended to use CAPTCHA - field Use Captcha when recovering a password In the settings of the main module.


Bitrix, 2001-2019, 1C-Bitrix, 2019

On the past, we figured out which blocks will be a TRIP template, so you can proceed to work. To begin with, create two folders:

images - This folder will contain any graphic files used to design a template. Because We have no designer workers, then throw one of the graphic file to this folder in this folder, otherwise the Joomla will not install the template and will issue an error if the folder is empty.

ATTENTION: In the Images folder, the template does not place the content graphics!

cSS - this folder will contain files Cascading Style Tables. To begin with, put an empty template.css file in it, with which the purpose of various design styles of the site elements will be applied.

Next, you can start creating the most important index.php file, which will determine the visual location of the site elements and report the CMS Joomla to which block to place various components and modules. The file is a combination of PHP and HTML.

I always use the code only Macromedia Dreamweaver. Excellent program, I strongly advise her beginners, because If in the process of working on the code you made an error, the program will definitely highlight your jamb.

On the site you will find a tutorial on Macromedia Dreamweaver. If you are going to develop sites, then the program is worth mastering this, at least at the initial level to edit template codes without errors.

Positioning the items (blocks) of the page is made using the HTML code, specifically, we will use the DIV tags. But as our website will work on the Joomla engine, i.e. It will be dynamic, then the PHP language will also have to use. With it, we define in which blocks will be positions for the output of modules, and how these positions will be called whether blocks will be folded or not. Connect the style sheets from external files, content language, install how to change the size of the site, etc.

index.php.

File title

The file header consists of several parts. The first part of the PHP code header is designed to ensure that the file does not directly turn directly, for safety reasons.

< ?php
defined ("_jexec") or DIE;
JHTML :: _ ("Behavior.Framework", True);
$ App \u003d JFactory :: getApplication ();
?>
< ?php echo "< ?" ; ?\u003e XML Version \u003d "1.0" encoding \u003d " < ?php echo $tHIS-\u003e _charset?\u003e "?>

DoCtype is a very important parameter, on the basis of which the browser decides, how to display this page and how to interpret CSS.

< ! DOCTYPE html PUBLIC "- / / W3C / / DTD XHTML 1.0 STRICT / / EN " "http: / / www.w3.org/ TR / XHTML1 / DTD / XHTML1- STRICT.DTD ">

The following fragment extracts the set language from the global configuration.

< html xmlns= "http:/ / www.w3.org/ 1999 / XHTML " XML: Lang \u003d " < ?php echo $tHIS-\u003e Language; ?\u003e " lang \u003d " < ?php echo $tHIS-\u003e Language; ?\u003e " dir \u003d " < ?php echo $tHIS-\u003e Direction; ?\u003e " >

Next comes a code fragment, which includes additional information for the title, which is specified in the global configuration. You can see this information looking at the source code of any web page. In particular, this is meta tags that you already know.

< head>
< jdoc:include type= "head" / >

The following lines in the title contain links to the main CSS Joomla styles.

< link rel= "stylesheet" href= "< ?php echo $tHIS-\u003e BaseURL?\u003e / TEMPLATES / System / CSS / System .css " Type \u003d "Text / CSS " / >
< link rel= "stylesheet" href= "< ?php echo $tHIS-\u003e BaseURL?\u003e / Templates / System / CSS / General.css " Type \u003d "Text / CSS " / >

To use template design styles, make a link to a file containing cascading TEMPLATE.CSS styles, which lies in the CSS folder. It does not matter that this file is still empty, the main thing is to connect it, the design will be done later when we install the template on Joomla. So it will be easier to observe the result.

< link rel= "stylesheet" href= "< ?php echo $tHIS-\u003e BaseURL?\u003e / TEMPLATES /< ?php echo $tHIS-\u003e Template?\u003e / css / template.css " Type \u003d "Text / CSS " / >

The following code fragment allows us to turn the left or right speakers if there are no single module in the "Left" and "Right" positions. If both columns are minimized, the content takes 100% of the page width. If only one column is included, the content takes 80%. At two on columns on the content accounts for 60% of the width of the page.

< ?php
if ($ tHIS-\u003e CountModules ("Left and Right") \u003d \u003d 0) $ contentwidth \u003d "100";
if ($ tHIS-\u003e CountModules ("Left or Right") \u003d \u003d 1) $ contentwidth \u003d "80";
if ($ tHIS-\u003e CountModules ("Left and Right") \u003d \u003d 1) $ contentwidth \u003d "60";
?>

The title is closed

< / head>

< body>

Block "Page" contains design only the page of the site, it is it that will be width of 950r.

< div id= "page" >

The "TOP" block is at the very top of the page and contains two "logo" and "user1" block.

< div id= "top" >

In the side "logo" we will place a graphic logo file, it will be spelled out in style tables. But the automatic output of the site name is prescribed in the index.php file, and the name is placed in the H1 tag, which is very important for search engine optimization.

< div id= "logo" >
< h1> < ?php echo $app - > getcfg ("Sitename"); ?\u003e< / h1>
< / div>

We define the position "User1" in the block of the same name to output the search module.

< div id= "user1" >
< jdoc:include type= "modules" name= "user1" style= "xhtml" / >
< / div>
< / div> < ! - - конец блока top - - >

The output of the horizontal menu module in the "User2" block in the "User2" position. The block will be folded if there is no module in this position.

< ?php if ($tHIS-\u003e CountModules ("User2")):?\u003e
< div id= "user2 " >
< jdoc:include type= "modules" name= "user2" style= "xhtml" / >
< / div>
< ?php endif ; ?>

Further there is a block caps of the site "Header". In it, we will define the "Header" position for the output of modules. The block will be folded if there is no module in this position. I intentionally expanded the capabilities of this block to be able to place in it not only the picture of the caps, but also image rotators.

< ?php if ($tHIS-\u003e CountModules (" header ") ) : ?>
< div id= "header ">
< jdoc:include type= "modules" name= "header " STYLE \u003d "XHTML" /\u003e
< / div>
< ?php endif ; ?>

In the "User3" block, we define the "User3" position for the output of modules.

The unit will be folded if the module will not be displayed in this position "User3".

< ?php if ($tHIS-\u003e CountModules ("User3")):?\u003e
< div id= "user3" >
< jdoc:include type= "modules" name= "user3" style= "xhtml" / >
< / div>
< ?php endif ; ?>

The left column block opens, which will be folded if there is no module in the position "Left".

< ?php if ($tHIS-\u003e CountModules ("Left")):?\u003e
< div id= "left" >
< jdoc:include type= "modules" name= "left" style= "xhtml" / >
< / div>
< ?php endif ; ?>

The most important content block opens, which can occupy 100% of the width of the page, 80% and 60%, depending on the number of columns on.

< div id= "content< ?php echo $contentwidth ; ?> " >

Displaying messages in components

< jdoc:include type= "message" / >

Content content output.

< jdoc:include type= "component" style= "xhtml" / >
< / div> < ! - - конец блока контента- - >

The block of the right column opens, which will be folded if there will be no module in the RIGTH position.

< ?php if ($tHIS-\u003e CountModules ("Right")):?\u003e
< div id= "rigth" >
< jdoc:include type= "modules" name= "right" style= "xhtml" / >
< / div>
< ?php endif ; ?>

The output of the "Footer" block designed to display the HTML code module with copyright information. You can also place the bottom horizontal menu or the content representation module. The block will be folded if not one module will be displayed in this position "Footer"

< ?php if ($tHIS-\u003e Countmodules ("Footer")):?\u003e
< div id= "footer" >
< jdoc:include type= "modules" name= "footer" style= "xhtml" / >
< / div>
< ?php endif ; ?>

Close block page page "Page", Body and all code.

< / div> < ! - - конец блока page- - >
< / body> < ! - - конец блока body - - >
< / html> < ! - - конец кода- - >

We have created a full-fledged file index.php. Now you know, with what commands, and in which sequence are displayed template blocks.

ATTENTION: In order for the template code to be read from the Joomla adminpanel, the index.php file must be opened in the AKELPAD editor and save the UTF-8 encoding, while removing the BOM tick. If you used to work with the Macromedia Dreamweaver program, then you need to select "Change"\u003e "Page Properties" and select Unicode Properties (UTF-8), while uninstalling "Turn on Unicode signatures (VOM)." However, I strongly advise you to edit the code from the Joomla admin admin, if there is no coming road - there is no road road, unlike the Macromedia Dreamweaver program, where you can always cancel the changes made.

The block design itself will be described in TEMPLATE.CSS. But we will set up styles tables after installing the template on Joomla 3 (Joomla 2.5), and for this you need to create

REG.RU: Domains and Hosting

The largest recorder and hosting provider in Russia.

More than 2 million domain names for maintenance.

Promotion, mail for a domain, business solutions.

More than 700 thousand customers worldwide have already made their choice.

* Mouse over to suspend scroll.

Back forward

Creating a simple user registration system for PHP and MySQL

Creating a registration system is a big job. You have to write a code that executes email addresses, sends a message to the mail confirmation, and also performs the validation of the remaining form fields, and much more.

And even after you write all this, users will register reluctantly, because This requires certain efforts on their part.

In this lesson, we will create a very simple registration system that does not require and does not store passwords in general! The result will be easy to change and add to an existing PHP site. Want to figure out how it works? Read below.



Here's how our super simple system will work:

We combine the form of authorization and registration. In this form there will be a field for entering an email address and a registration button;
- When filling out the Email address field, a new user will be created by clicking on the registration button, but only if the email address entered is not found in the database.

After that, a certain random unique set of characters (token) is created, which is sent to the user specified by the user in the form of a reference, which will be relevant within 10 minutes;
- By link, the user goes to our site. The system determines the presence of a token and authorizes the user;

The advantages of this approach:

No need to store passwords and carry out field validation;
- there is no need to restore password, secret questions, etc.;
- from the moment the user has registered / authorized you can always be sure that this user will be in your access area (that the Email address is true);
- incredibly simple registration process;

Disadvantages:

User Account Security. If someone has access to the mail, it can log in.
- Email is not protected and can be intercepted. Keep in mind that this question is relevant and in the case when the password has been forgotten and it must be restored, or in any authorization system that does not use HTTPS for data transfer (login / password);
- While you configure how you need a mail server, there is a chance that messages with links to authorization will be in spam;

Comparing the advantages and disadvantages of our system, it can be said that the system has high yuzability (most convenient for the end user) and, at the same time, has a low security indicator.

So use it is offered for registrations on forums and services that do not work with important information.

How to use this system

In the case when you just need to use the system to authorize users on your site, and you do not want to disassemble this lesson on the bones, that's what you need to do:

You need to download sources attached to the lesson
- Find file in the archive tables.sql Import it to your database using the import option in PHPMYAdmin. Alternative way: Open this file through a text editor, copy the SQL query and execute it;
- Open includes / main.php. and fill in communication settings with your database (specify a user and password to communicate with the base as well as the host and name of the base). In the same file, you must also specify email, which will be used as the original address for messages sent by the system. Some hosts block outgoing mails while the form does not specify this email address, which was created from the host control panel, so specify the real address;
- Load all files index.php., protected.php. And the Assets and Includes folders via FTP on your host;
- add the code below to each PHP page, where you need to display the authorization form;

Require_ONCE "includes / main.php"; $ User \u003d NEW User (); if (! $ user- & gtloggedin ()) (redirect ("index.php");)
- Ready!

For those who are interested, how it all works - forward to reading below!

The first step is to write the HTM-code of the authorization form. This code is located in the file. index.php.. This file also contains a PHP code that machines the form data and other useful functions of the authorization system. You can learn more in the section below dedicated to the PHP code review.

index.php.

Tutorial: Super Simple Registration System WITH PHP & MySQL

Login or Register.

ENTER YOUR EMAIL ADDRESS ABOVE AND WE WILL SEND
you a a login link.

In the head section (between tags and) I connected the main styles (in this lesson they do not understand, so you can see them yourself. The ASSETS / CSS / STYLE.CSS folder). To the closing tag I connected the jQuery library and the script.js file, which we will write and wonder just below.


Javascript.

jQuery tracks the status of the "Register / Authorine" button using the function e.PreventDefault () And sends Ajax requests. Depending on the server response, it displays this or that message and determines further actions /

aSSETS / JS / Script.js

$ (Function () (var form \u003d $ ("# login-register"); form.on ("Submit", Function (E) (if (Form.is (". Loading, .loggedin")) (Return False ;) var email \u003d form.find ("Input"). Val (), MessageHolder \u003d form.find ("Span"); E.PreventDefault (); $ .post (this.action, Email: Email), Function (M) (Form.AddClass ("Error"); MessageHolder.Text (M.Message);) ELSE (Form.RemoveClass ("Error"). AddClass ("Loggedin"); MessageHolder. Text (M.Message);)));)); $ (Document) .Ajaxstart (FUNCTION ();)); $ (Document) .ajaxcomplete (FUNCTION () (Form. Removeclass ("Loading");));));

was added to the form to display the current state of the AJAX request (this became possible due to the methods ajaxstart ()) I. ajaxcomplete ()which you can find closer to the end of the file).

This class shows a spinning animated GIF file (as if hinting that the request is processed), and also acts as a flag that prevents the form of re-sending (when the register button has already been pressed once). Class .loggedin. - This is another flag, is set when email has been sent. This flag instantly blocks any further action with the form.

Database schema

Our incredibly simple registration system uses 2 MySQL tables (SQL code is in the file tables.sql). The first stores data on user accounts. The second stores information on the number of input attempts.


User table circuit.

The system does not use passwords, which is visible in the diagram. You can see the column token. with tokens adjacent to column token_validity. The token is installed as soon as the user connects to the system, sets its email to send a message (a little more about this in the next block). Speaker token_validity Sets the time 10 minutes later, after which the token ceases to be relevant.


Table circuit, which considers the number of authorization attempts.

In both tables, the IP address is stored in the processed form using the IP2Long function in the Integer field.

Now we can write a little PHP code. The main functionality of the system is entrusted to the class User.class.php.which you can see below.

This class actively uses IDORM (DOCS), these libraries are minimally necessary tools to work with databases. It processes access to the database, generation of tokens and their validation. It is a simple interface that allows you to easily connect the registration system to your site if it uses PHP.

User.class.php.

Class User (// Private ORM case Private $ orm; / ** * Find a user on Tocken. Only valid tokens are taken to consideration. Tocken is generated only for 10 minutes from the moment * @param String $ Token. This is the desired Tocken * @return user. Return the value of the function user * / public Static Function Findbytoken ($ token) (// Find a token in the database and make sure that the current time stamp $ result \u003d ORM :: FOR_TABLE ("REG_USERS") -\u003e WHERE ("Token", $ token) -\u003e where_raw ("token_validity\u003e now ()") -\u003e find_one (); if (! $ Result) (Return False;) Return New User ($ Result);) / ** * Authorize or register a user * @param String $ email. Custom email address * @return user * / public address ($ email) (// If such a user already exists, return the value of the user function from the specified email address stored in the database if (User :: EXISTS ($ email)) (Return New User ($ email);) // otherwise create a new user TV in the database and return the value of the function User :: Create from the specified Email Return User :: Create ($ email); ) / ** * Create a new user and save to the database * @param String $ Email. User email address * @return user * / Private Static Function Create ($ email) (// Write a new user and return the result of the user function from these values \u200b\u200b$ result \u003d orm :: for_table ("reg_users") -\u003e create (); $ result-\u003e email \u003d $ email; $ Result-\u003e Save (); Return New User ($ result);) / ** * Check if such a user exists in the database and return the Variable value of the variable * @param String $ email. Custom Email Address * @return Boolean * / Public Static Function Exists ($ email) (// Is there a user in the database? $ Result \u003d orm :: for_table ("reg_users") -\u003e Where ("Email", $ email) -\u003e count (); return $ result \u003d\u003d 1;) / ** * Create a new user object * @param instance $ param orm, ID, email or 0 * @return user * / public function __construct ($ param \u003d null) (If ($ param instanceof ORM) (// ORM Check is passed $ this-\u003e orm \u003d $ param;) ELSE if (IS_String ($ param)) (// Email checking $ this-\u003e om \u003d om :: for_table ("REG_USERS") -\u003e WHERE ("Email", $ param) -\u003e find_one ();) else ($ id \u003d 0; if (IS_Numeric ($ param)) (// user identifier is transmitted to the value of the $ param $ ID value \u003d $ param;) ELSE if (ISSET ($ _ session ["loginid"])) (// otherwise see the session $ id \u003d $ _session ["Loginid"];) $ this-\u003e orm \u003d orm :: for_table ( "REG_USERS") -\u003e WHERE ("ID", $ ID) -\u003e find_one ();)) / ** * Generate new SHA1 authorization token, writes In the database and returns its value * @return string * / public function generatetoken () (// Generate a token for an authorized user and save it to $ TOKEN \u003d SHA1 ($ this-\u003e email.time (). Rand (0, 1000000 )); // Save tokens in the database // and mark it that it is relevant only within 10 of the following minutes $ this-\u003e orm-\u003e set ("Token", $ token); $ this-\u003e orm-\u003e set_expr ("token_validity", "addtime (now ()," 0:10 ")"); $ this-\u003e om-\u003e save (); Return $ Token; ) / ** * authorize the user * @return void * / public function login () (// Mark a user as authorized $ _session ["loginid"] \u003d $ this-\u003e orm-\u003e ID; // Refresh the value of the Last_Login base field $ this-\u003e om-\u003e set_expr ("last_login", "now ()"); $ this-\u003e orm-\u003e save ();) / ** * destroy the session and divodes the user * @return void * / public function logout () ($ _Session \u003d array (); unset ($ _ session);) / ** * Check, whether the user came * @return boolean * / public function loggedin () (Return Isset ($ this-\u003e orm-\u003e ID) && $ _Session ["LoginID"] \u003d\u003d $ this-\u003e orm-\u003e ID;) / ** * Check is the user administrator * @return boolean * / public function isadmin () (Return $ this-\u003e Rank () \u003d \u003d "Administrator";) / ** * Find a user type, maybe either Administrator or regular * @return string * / public function Rank () (if ($ this-\u003e orm-\u003e Rank \u003d\u003d 1) (Return "Administrator ";) Return" regular ";) / ** * Method allows you to get private infor user account in * quality properties of the user * @Param String $ Key property feature receiving access * @return Mixed * / public function __get ($ Key) (IF (ISSET ($ this-\u003e Ор -\u003e $ Key)) (Return $ this-\u003e orm -\u003e $ Key; ) Return NULL; ))

Tokens are generated using the SHA1 algorithm and are stored in the database. I use MySQL time functions, in order to set a 10-minute restriction of the relevance of the tokeny.

When the token passes the validation procedure, we are directly talking to the handler that we consider only tokens who have no expiration date, stored in the TKEN_VALIDY column.

Note that I use the magic method __get. DOCS libraries at the end of the file to intercept access to the properties of the user object.

Due to this, it becomes possible to access the information stored in the database, thanks to the properties $ User-\u003e Email, $ User-\u003e Token et al. In the following code fragment, consider for an example, how to use these classes.


Protected page

Another file that stores useful and necessary functionality is a file. functions.php.. There are several so-called helpers - assistant functions that allow you to create a cleaner and readable code in other files.

functions.php.

Function Send_email ($ from, $ to, $ subject, $ message) (// Helper, sending email $ Headers \u003d "Mime-Version: 1.0". "\\ R \\ n"; $ Headers. \u003d "Content-Type: Text / Plain; Charset \u003d UTF-8 "." \\ R \\ n "; $ Headers. \u003d" From: ". $ from." \\ R \\ n "; Return Mail ($ to, $ Subject, $ Message, $ Headers );) Function Get_Page_URL () (// Determine the US PHP file URL \u003d "HTTP". (Empty ($ _ Server ["https"])? "": "S"). ": //" $ _ Server ["Server_name"]; if (ISSET ($ _ Server ["Request_uri"]) && $ _Server ["Request_uri"]! \u003d "") ($ URL. \u003d $ _Server ["Request_uri"];) ELSE ($ URL. \u003d $ _Server ["path_info"];) Return $ URL;) FUNCTION RATE_LIMIT ($ ip, $ limit_hour \u003d 20, $ limit_10_min \u003d 10) (// The number of input attempts for the last hour on this IP address $ COUNT_HOUR \u003d ORM: : for_table ("reg_login_attempt") -\u003e WHERE ("IP", SPRINTF ("% U", IP2LONG ($ ip))) -\u003e where_raw ("TS\u003e Subtime (now ()," 1:00 ")") -\u003e Count (); // Number of input attempts in the last 10 minutes on this IP address $ Count_10_min \u003d ORM :: FOR_TABLE ("REG_LOGIN_ATTEMPT") -\u003e WHERE ("IP", SPRINT f ("% u", ip2long ($ ip))) -\u003e where_raw ("TS\u003e subtime (now ()," 0:10 ")") -\u003e count (); if ($ count_hour\u003e $ limit_hour || $ count_10_min\u003e $ limit_10_min) (Throw New Exception ("Too Many Login Attempts!");)) Function rate_Limit_Tick ($ ip, $ email) (// Create a new entry in the table that considers Number of input attempts $ login_attempt \u003d ORM :: FOR_TABLE ("REG_LOGIN_ATTEMPT") -\u003e create (); $ login_attempt-\u003e email \u003d $ email; $ login_attempt-\u003e ip \u003d sprintf ("% u", IP2Long ($ ip)); $ login_attempt-\u003e save ();) Function Redirect ($ URL) (Header ("Location: $ URL"); exit;)

Functions rate_limit. and rate_limit_tick. They are followed by the number of authorization attempts for the expired period of time from the moment of the first attempt. The input attempt is recorded in the database in the reg_login_attempt column. These functions are called when processing and sending the form data as you can see from the next code fragment.

The code is taken from the file below. index.php. And it processes the sending of the form. It returns a JSON response, which, in turn, is processed by jQuery in the file aSSETS / JS / Script.jswhich we have already disassembled earlier.

index.php.

Try (if (! Empty ($ _ post) && isset ($ _ server ["http_x_requested_with"])) (// Output A JSON Header Header ("Content-Type: Application / JSON"); // Is this email address Valid If (! Isset ($ _ post ["email"]) ||! filter_var ($ _ post ["email"], filter_validate_email)) (Throw New Exception ("Please Enter A Valid Email");) // Check. Whether the user is allowed to log in, does it exceed the number of permissible connections? (Functions.php file for more information) rate_limit ($ _ server ["remote_addr"]); // Record this attempt to authorize Rate_Limit_Tick ($ _ Server ["Remote_ADDR"], $ _Post ["email"]); // Send a letter to the user $ message \u003d ""; $ email \u003d $ _post ["email"]; $ subject \u003d "Your Login Link"; if (! User :: Exists ($ email) ) ($ subject \u003d "thank you for registering!"; $ message \u003d "Thank you for Registering at OUR Site! \\ N \\ n";) // Attempt to authorize or register the user $ User \u003d User :: LoginorRegister ($ _ post [ "Email"]); $ message. \u003d "You can login from this url: \\ n" ; $ message. \u003d get_page_url (). "? TKN \u003d". $ User-\u003e GenerateToken (). "\\ N \\ n"; $ Message. \u003d "The Link Is Going Expire Automatically After 10 Minutes."; $ resulting \u003d send_email ($ Fromemail, $ _post ["email"], $ subject, $ message); If (! $ Result) (Threw New Exception ("There Was An Error Sending Your Email. Please Try Again.");) DIE (JSON_ENCODE (Array ("Message" \u003d\u003e "Thank You! WE \\" Ve Sent A Link To Your Inbox. Check Your Spam Folder AS Well. ")));)) Catch (JSON_ENCODE (Array (Error" \u003d\u003e 1, "Message" \u003d\u003e $ E-\u003e GetMessage () )));)

After successful authorization / registration code, the user will send a link to authorization to the user. Tocken becomes affordable, because It is transmitted as a variable in the generated link method $ _Get. With TKN marker

index.php.

If (ISSET ($ _ get ["TKN"])) (// Is this token valid for authorization? $ User \u003d User :: FindbyToken ($ _ get ["TKN"]); if ($ User) (// Yes is. To make a redirect to the protected page of $ User-\u003e login (); Redirect ("Protected.php");) // No, the token is not valid. Implement a redirect, on the page with the form of authorization / registration of Redirect ("index.php ");)

$ User-\u003e Login ()

create the necessary variables for the session, so that the user, looking through the subsequent site pages, will remain authorized all the time.

Similarly, the processing of the function to exit the system is also arranged.

index.php.

If (ISSET ($ _ get ["logout"])) ($ user \u003d new user (); if ($ user-\u003e loggedin ()) ($ User-\u003e logout ();) redirect ("index.php") ;)

At the end of the code, I again put a redirect on index.php, thus the parameter ? LOGOUT \u003d 1 Not required by the URL is not required.

Our file. index.php. requires add. Protection - We do not want people who ever once logged in the system again saw the registration form. For these purposes, we use the method $ User-\u003e Loggedin ().

index.php.

$ User \u003d NEW User (); if ($ User-\u003e Loggedin ()) (Redirect ("Protected.php");)

Finally, here is a piece of code that allows you to protect the pages of your site and make it available only after authorization.

protected.php.

// To protect each page on your site, connect the file // Main.php to it and create a new User object. That's how easy it is! Require_ONCE "includes / main.php"; $ User \u003d NEW User (); If (! $ User-\u003e Loggedin ()) (Redirect ("index.php");)

After this check, you can be sure that the user has been successfully authorized. You can also access stored information in the database using the object properties. $ User.. To display email and user and its status, use this code:

Echo "Your Email:" $ User-\u003e Email; Echo "Your Rank:" $ User-\u003e Rank ();

Method rank () Used here because the database is usually stored (0 for a regular user, 1 for the administrator) and we need to convert this data to the statuses to which they relate to us and this method helps.

To make an administrator from a regular user, simply edit the user entry via phpMyAdmin (or any other program that allows you to manage databases). Administrator status does not give any privileges, in this example on the page will be displayed that you are an administrator - and that's it.

But what to do with it - it remains at your discretion, you can write and create a code that defines certain privileges and opportunities for administrators.

We finished!

With this incredibly super quasi simple form, we finished! You can use it in your php sites, it's easy enough. You can also modify it under yourself and make it like you want.

Material Prepared Denis Baby specially for site site

P.S. Want to move on in mastering PHP and OOP? Pay attention to premium lessons on various aspects of site buildings, including PHP programming, as well as a free course on creating your CMS system on PHP from zero using OOP:

Did you like the material and want to thank?
Just share with friends and colleagues!