In CMS 1C-Bitrix, the developers are presented with four system components for implementing authorization functions, changing the password and registering ordinary users of the system (system.auth. *), But there is
no official documentation of these. In this article, you will learn the limitations and disadvantages of using these components, why you should use them, how best to use them, and perhaps make some conclusions about why there is no documentation.
Principle of operation
By default, old components 1.0 are used for authorization and registration, the use of which is undesirable. You can fix this by ticking “Use Components 2.0 for authorization and registration” in the settings of the main module or by running the code once:
COption::SetOptionString('main', 'auth_comp2', 'Y');
After reviewing the description
of the page execution order, we see that in step 1.13 (even before the output of header.php from the site template) a level 1 access right check is in place and if it is not passed, the authorization form is displayed. Let us examine this in more detail.
Calling the registration form means the following actions:
- the page execution order continues to be executed without changes up to point 3 “Body of the page”, including the execution of header.php,
- instead of “Page Body”, depending on the variables passed to $ _REQUEST, one of the system components system.auth. * Is connected (specifically system.auth.authorize if $ _REQUEST is empty) to which special parameters are passed (about this below),
- the page execution order continues to be executed without changes, including the execution of footer.php.
This allows you to implement your own design (template) for the system.auth.authorize component, organically fitting into the site template between the header and the basement.
Verification of access rights "level 1" initiates a call to the authorization form in the following cases:
- if the global constant NEED_AUTH is defined and equal to true,
- if the user (including unregistered) does not have sufficient rights to read the file requested by him.
')
Permissions to read files and sections for different groups of users are formed when the administrative panel edits these in service files .access.php. Each file describes the levels of access to files and directories located at the same level with it. It is possible to create an .access.php file for each directory in the public part of the site, each subsequent such file complements the access rules for the chain of directories. An example of such a file in the root of the site:
<? $PERM["/"]["*"]="D";
This distribution of rights allows you to literally “on the spot” to request the username and password of the user in cases when he goes without active authorization to the directory whose functionality requires authorization. This often happens if the user keeps a link not in the root of the site, but in the specific section with which he works most. As a result, the user enters the login and password without leaving the landing page, they are sent to its URL, instead of the page, the system component processes the received data, either raises an error or authorizes and reloads the page. The user is satisfied, he does not need to make an extra click to go to the desired section. The programmer is satisfied, he does not need to think about redirects to / auth / and $ backurl.
I recommend using the global constant NEED_AUTH only in specific cases, one of which is the authorization page itself in the standard package of the demo site at /auth/index.php:
<? define("NEED_AUTH", true); require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); IncludeModuleLangFile($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/intranet/public/about/auth/index.php");
This script transfers control to the Bitrix kernel, before defining the constant NEED_AUTH. Bitrix, in case the user is not authorized, connects the header + system component (authorization) + basement and dies, not allowing the script to run beyond the second line. If the user is authorized, he will receive a welcome message and a link to the root of the site.
Other system components
Let me remind you that when initiating authorization, instead of “Page Body”, the system.auth.authorize component will connect with the Bitrix kernel only if the user has not explicitly requested any other system component from the list:
-? Forgot_password = yes connect system.auth.forgotpasswd (send control word to change password),
-? Change_password = yes will connect system.auth.changepasswd (password change according to the control word),
-? Register = yes connect system.auth.registration (registration),
-? Confirm_registration = yes connect system.auth.confirmation (registration confirmation).
This approach allows the user to recover the password or even register an account without leaving the landing page. You can manipulate the available set of these links in your system component templates, but you cannot prevent them from being called when clicking on these links, and this is a fat minus.
Using the authorization component inside the page body
Sometimes it is required to embed an authorization form not instead of the page body, but inside the page body, for example, at /about/index.php in the middle of the content. And here comes a
nuance : it turns out that the system component of system.auth.authorize does absolutely nothing with respect to direct authorization, and therefore does not know anything about the result of authorization. Therefore, if we connect a component without parameters, it will correctly authorize users, but will not display authorization errors. In fact, the authorization mechanism occurs somewhere deep in the core of the kernel, after which the kernel connects the component, passing the “AUTH_RESULT” parameter to it by setting a value from $ APPLICATION-> arAuthResult that we have to repeat on our pages:
<? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php"); $APPLICATION->SetTitle(" "); ?> ... <? if (!$USER->IsAuthorized()): ?> <? $APPLICATION->IncludeComponent('bitrix:system.auth.authorize', '', array('AUTH_RESULT' => $APPLICATION->arAuthResult)); ?> <? endif; ?> ... <? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>
If the need for authorization arises during the execution of the component, you should call the authorization form using the CMain :: AuthForm () method, which will allow the user to authorize not only without leaving the landing page, but also save all the parameters in the URL:
$APPLICATION->AuthForm(array( "MESSAGE" => " ... .", "TYPE" => "OK", ));
Creating your own templates
In order to customize the appearance of the system authorization forms, registration, change password request and password change on the control line, you should copy the existing templates of these components (/bitrix/components/bitrix/system.auth.*/templates/.default) into the template site (/bitrix/templates/ <site_colation >/components/bitrix/system.auth.*/.default), then work with them. You cannot change the names of the transmitted fields in these forms, but you can add any other fields, for example, “phone” to the registration, though at this stage the system component will not understand what you want from it with these new fields. You can also completely change the design and adjust the display of links to neighboring system components. When processing these templates, pay attention to the output of messages by the global ShowMessage function, which accepts a string or array as input. You can get rid of its use, but it is better to override the template system.show_message component.
Expansion of registration functionality
Unfortunately, today system components are implemented in a procedural style, which does not allow you to inherit your own components from them, redefining and complementing the functionality, so you need to use Bitrix events to solve such problems. The two most interesting events generated by user registration are:
OnBeforeUserRegister and
OnAfterUserAdd . Ideally, handlers for these events are registered when the module is installed, deleted when the module is deleted, for example:
The OnBeforeUserRegister event is remarkable in that it is not called during a regular user addition, be it an API call or manual addition in the administrative part, which allows changing the logic of the guest user registration, imposing additional restrictions on the fields or processing additional fields, for example, controlling the numbers in the phone , control the availability of data in the name and surname.
class CWBroker {
The task of the event handler is to correct the incoming data array $ arArgs or declare an error using the CMain :: ThrowException () method, returning false instead of the data array. Unfortunately, to ensure that the fields of interest to us are passed through $ arArgs is impossible, so you have to analyze $ _REQUEST. The listing can be improved by grouping the errors found, but unfortunately, even if the handler successfully completes, there may be other errors later in the registration process in the kernel that we cannot influence. The user is not satisfied, receiving various errors in the registration process. The programmer is looking for alternatives.
The OnAfterUserAdd event is triggered not only after successful user self-registration, but also when API calls or adding a user to the administrative part, but the data array sent to the event handlers does not affect anything other than the handlers themselves, therefore, it is almost useless to generate exceptions, but instead you can do some common logic for all new users, such as: add a user to the mailing list, create a budget for it in the online store, or assign some custom property
class CWBroker {
Alternatives
If you have the courage to get into the source code of the system components (authorization), then you have drastically lost any desire to work with them. As an obvious alternative, first of all, creating your own authorization, registration and other components comes to mind. The benefit of the API allows you to implement all the same. However, in this alternative, I see the following fat cons:
- the cost of re-implementation of logic (in only one component of the authorization: test captcha, secure key authorization and authorization through external services),
- refusal to update the considered system components, which is especially important with the gradual
transition of the core to D7 ,
- the inability to connect your own authorization component to the user's target page in the case when he does not have enough rights to view the page, instead, he has to implement his own logic of the availability of certain pages and sections.
Another alternative is the
bitrix: main.register component , which has a wide range of parameters. However, in order for this component to be displayed and worked out on the user's target page, the programmer has to go to the trick: insert the call of this component into the registration system component template (bitrix: system.auth.register), which entails the following disadvantages:
- the same set of component parameters is stored in at least two places: in the public part on the authorization page and in the site template,
- when calling bitrix: main.register through the bitrix: system.auth.register component template, the latter’s code is wasted.
Finally
It's no secret that the Bitrix platform is far from ideal. Every time I see such things that distort my poker interface, I first call them
strange , then I try to figure out and understand
why it was done this way and in most cases I find
an acceptable answer. But in this case I did not find the answer, so I decided to write down all the thoughts about it. I hope someone will come in handy.