Configuration — phpMyAdmin 5.1.4 documentation

Что будем ваять

Продолжаем начатую несколько материалов назад тему создания динамических ресурсов. Сегодня мы замахнемся на более глобальные вещи! Мы создадим полноценную систему авторизации и регистрации для сайта на основе PHP.

Почему их не стоит реализовывать по отдельности? Ну, прежде все потому, что они тесно взаимосвязаны между собой. Оба модуля (регистрации и авторизации) используют одну и ту же таблицу в БД ресурса, в которую заносятся все сведения о новых пользователях сайта. А затем извлекаются (проверяются на соответствие) при авторизации.

Console settings

.. config:option:: $cfg['Console']['StartHistory']

    :type: boolean
    :default: false

    Show query history at start

.. config:option:: $cfg['Console']['AlwaysExpand']

    :type: boolean
    :default: false

    Always expand query messages

.. config:option:: $cfg['Console']['CurrentQuery']

    :type: boolean
    :default: true

    Show current browsing query

.. config:option:: $cfg['Console']['EnterExecutes']

    :type: boolean
    :default: false

    Execute queries on Enter and insert new line with Shift Enter

.. config:option:: $cfg['Console']['DarkTheme']

    :type: boolean
    :default: false

    Switch to dark theme

.. config:option:: $cfg['Console']['Mode']

    :type: string
    :default: 'info'

    Console mode

.. config:option:: $cfg['Console']['Height']

    :type: integer
    :default: 92

    Console height

Database structure

.. config:option:: $cfg['ShowDbStructureCreation']

    :type: boolean
    :default: false

    Defines whether the database structure page (tables list) has a
    "Creation" column that displays when each table was created.

.. config:option:: $cfg['ShowDbStructureLastUpdate']

    :type: boolean
    :default: false

    Defines whether the database structure page (tables list) has a "Last
    update" column that displays when each table was last updated.

.. config:option:: $cfg['ShowDbStructureLastCheck']

    :type: boolean
    :default: false

    Defines whether the database structure page (tables list) has a "Last
    check" column that displays when each table was last checked.

.. config:option:: $cfg['HideStructureActions']

    :type: boolean
    :default: true

    Defines whether the table structure actions are hidden under a ":guilabel:`More`"
    drop-down.

.. config:option:: $cfg['ShowColumnComments']

    :type: boolean
    :default: true

    Defines whether to show column comments as a column in the table structure view.

Default options for transformations

.. config:option:: $cfg['DefaultTransformations']

    :type: array
    :default: An array with below listed key-values

.. config:option:: $cfg['DefaultTransformations']['Substring']

    :type: array
    :default: array(0, 'all', '…')

.. config:option:: $cfg['DefaultTransformations']['Bool2Text']

    :type: array
    :default: array('T', 'F')

.. config:option:: $cfg['DefaultTransformations']['External']

    :type: array
    :default: array(0, '-f /dev/null -i -wrap -q', 1, 1)

.. config:option:: $cfg['DefaultTransformations']['PreApPend']

    :type: array
    :default: array('', '')

.. config:option:: $cfg['DefaultTransformations']['Hex']

    :type: array
    :default: array('2')

.. config:option:: $cfg['DefaultTransformations']['DateFormat']

    :type: array
    :default: array(0, '', 'local')

.. config:option:: $cfg['DefaultTransformations']['Inline']

    :type: array
    :default: array('100', 100)

.. config:option:: $cfg['DefaultTransformations']['TextImageLink']

    :type: array
    :default: array('', 100, 50)

.. config:option:: $cfg['DefaultTransformations']['TextLink']

    :type: array
    :default: array('', '', '')

Design customization¶

$cfg['NavigationTreePointerEnable']

When set to true, hovering over an item in the navigation panel causes that item to be marked
(the background is highlighted).

$cfg['BrowsePointerEnable']

When set to true, hovering over a row in the Browse page causes that row to be marked (the background
is highlighted).

$cfg['BrowseMarkerEnable']

When set to true, a data row is marked (the background is highlighted) when the row is selected
with the checkbox.

$cfg['LimitChars']

Maximum number of characters shown in any non-numeric field on browse
view. Can be turned off by a toggle button on the browse page.

Похожее:  Госуслуги личный кабинет — вход через СНИЛС или по номеру телефона, gosuslugi ru

Editing mode

.. config:option:: $cfg['ProtectBinary']

    :type: boolean or string
    :default: ``'blob'``

    Defines whether ``BLOB`` or ``BINARY`` columns are protected from
    editing when browsing a table's content. Valid values are:

    * ``false`` to allow editing of all columns;
    * ``'blob'`` to allow editing of all columns except ``BLOBS``;
    * ``'noblob'`` to disallow editing of all columns except ``BLOBS`` (the
      opposite of ``'blob'``);
    * ``'all'`` to disallow editing of all ``BINARY`` or ``BLOB`` columns.

Main panel

.. config:option:: $cfg['ShowStats']

    :type: boolean
    :default: true

    Defines whether or not to display space usage and statistics about
    databases and tables. Note that statistics requires at least MySQL
    3.23.3 and that, at this date, MySQL doesn't return such information
    for Berkeley DB tables.

.. config:option:: $cfg['ShowServerInfo']

    :type: boolean
    :default: true

    Defines whether to display detailed server information on main page.
    You can additionally hide more information by using
    :config:option:`$cfg['Servers'][$i]['verbose']`.

Manual configuration

Please look at your ./sql/ directory, where you should find a
file called create_tables.sql. (If you are using a Windows server,
pay special attention to :ref:`faq1_23`).

If you already had this infrastructure and:

and then create new tables by importing :file:`sql/create_tables.sql`.

Mysql settings¶

$cfg['DefaultFunctions']

Functions selected by default when inserting/changing row, Functions
are defined for meta types as (FUNC_NUMBER, FUNC_DATE, FUNC_CHAR,
FUNC_SPATIAL, FUNC_UUID) and for first_timestamp, which is used
for first timestamp column in table.

Example configuration

Navigation panel setup¶

$cfg['ShowDatabasesNavigationAsTree']

In the navigation panel, replaces the database tree with a selector

$cfg['FirstLevelNavigationItems']

The number of first level databases that can be displayed on each page
of navigation tree.

$cfg['MaxNavigationItems']

The number of items (tables, columns, indexes) that can be displayed on each
page of the navigation tree.

$cfg['NavigationTreeEnableGrouping']

Defines whether to group the databases based on a common prefix
in their name $cfg['NavigationTreeDbSeparator'].

$cfg['NavigationTreeDbSeparator']

The string used to separate the parts of the database name when
showing them in a tree.

$cfg['NavigationTreeTableSeparator']

Defines a string to be used to nest table spaces. This means if you have
tables like first__second__third this will be shown as a three-level
hierarchy like: first > second > third. If set to false or empty, the
feature is disabled. NOTE: You should not use this separator at the
beginning or end of a table name or multiple times after another without
any other characters in between.

$cfg['NavigationTreeTableLevel']

Defines how many sublevels should be displayed when splitting up
tables by the above separator.

$cfg['NumRecentTables']

The maximum number of recently used tables shown in the navigation
panel. Set this to 0 (zero) to disable the listing of recent tables.

$cfg['NumFavoriteTables']

The maximum number of favorite tables shown in the navigation
panel. Set this to 0 (zero) to disable the listing of favorite tables.

Signon authentication mode

The very basic example of saving credentials in a session is available as
:file:`examples/signon.php`:

.. literalinclude:: ../examples/signon.php
    :language: php

Alternatively, you can also use this way to integrate with OpenID as shown
in :file:`examples/openid.php`:

.. literalinclude:: ../examples/openid.php
    :language: php

If you intend to pass the credentials using some other means than, you have to
implement wrapper in PHP to get that data and set it to
:config:option:`$cfg[‘Servers’][$i][‘SignonScript’]`. There is a very minimal example
in :file:`examples/signon-script.php`:

.. literalinclude:: ../examples/signon-script.php
    :language: php

.. seealso::
    :config:option:`$cfg['Servers'][$i]['auth_type']`,
    :config:option:`$cfg['Servers'][$i]['SignonSession']`,
    :config:option:`$cfg['Servers'][$i]['SignonCookieParams']`,
    :config:option:`$cfg['Servers'][$i]['SignonScript']`,
    :config:option:`$cfg['Servers'][$i]['SignonURL']`,
    :ref:`example-signon`

.. index:: pair: Config; Authentication mode

Sql query box settings

.. config:option:: $cfg['SQLQuery']['Edit']

    :type: boolean
    :default: true

    Whether to display an edit link to change a query in any SQL Query
    box.

.. config:option:: $cfg['SQLQuery']['Explain']

    :type: boolean
    :default: true

    Whether to display a link to explain a SELECT query in any SQL Query
    box.

.. config:option:: $cfg['SQLQuery']['ShowAsPHP']

    :type: boolean
    :default: true

    Whether to display a link to wrap a query in PHP code in any SQL Query
    box.

.. config:option:: $cfg['SQLQuery']['Refresh']

    :type: boolean
    :default: true

    Whether to display a link to refresh a query in any SQL Query box.

Text fields

.. config:option:: $cfg['CharEditing']

    :type: string
    :default: ``'input'``

    Defines which type of editing controls should be used for CHAR and
    VARCHAR columns. Applies to data editing and also to the default values
    in structure editing. Possible values are:

    * input - this allows to limit size of text to size of columns in MySQL,
      but has problems with newlines in columns
    * textarea - no problems with newlines in columns, but also no length
      limitations

.. config:option:: $cfg['MinSizeForInputField']

    :type: integer
    :default: 4

    Defines the minimum size for input fields generated for CHAR and
    VARCHAR columns.

.. config:option:: $cfg['MaxSizeForInputField']

    :type: integer
    :default: 60

    Defines the maximum size for input fields generated for CHAR and
    VARCHAR columns.

.. config:option:: $cfg['TextareaCols']

    :type: integer
    :default: 40

.. config:option:: $cfg['TextareaRows']

    :type: integer
    :default: 15

.. config:option:: $cfg['CharTextareaCols']

    :type: integer
    :default: 40

.. config:option:: $cfg['CharTextareaRows']

    :type: integer
    :default: 7

    Number of columns and rows for the textareas. This value will be
    emphasized (*2) for :term:`SQL` query
    textareas and (*1.25) for :term:`SQL`
    textareas inside the query window.

    The Char* values are used for CHAR
    and VARCHAR editing (if configured via :config:option:`$cfg['CharEditing']`).

    .. versionchanged:: 5.0.0

        The default value was changed from 2 to 7.

.. config:option:: $cfg['LongtextDoubleTextarea']

    :type: boolean
    :default: true

    Defines whether textarea for LONGTEXT columns should have double size.

.. config:option:: $cfg['TextareaAutoSelect']

    :type: boolean
    :default: false

    Defines if the whole textarea of the query box will be selected on
    click.

.. config:option:: $cfg['EnableAutocompleteForTablesAndColumns']

    :type: boolean
    :default: true

    Whether to enable autocomplete for table and column names in any
    SQL query box.

Upgrading from an older version

Simply copy :file:`config.inc.php` from your previous installation into
the newly unpacked one. Configuration files from old versions may
require some tweaking as some options have been changed or removed.

https://www.youtube.com/watch?v=LjkiSWkZDaY

The complete upgrade can be performed in a few simple steps:

Using ssl for connection to database server

It is recommended to use SSL when connecting to remote database server. There
are several configuration options involved in the SSL setup:

:config:option:`$cfg[‘Servers’][$i][‘ssl’]`
Defines whether to use SSL at all. If you enable only this, the connection
will be encrypted, but there is not authentication of the connection – you
can not verify that you are talking to the right server.
:config:option:`$cfg[‘Servers’][$i][‘ssl_key’]` and :config:option:`$cfg[‘Servers’][$i][‘ssl_cert’]`
This is used for authentication of client to the server.
:config:option:`$cfg[‘Servers’][$i][‘ssl_ca’]` and :config:option:`$cfg[‘Servers’][$i][‘ssl_ca_path’]`
The certificate authorities you trust for server certificates.
This is used to ensure that you are talking to a trusted server.
:config:option:`$cfg[‘Servers’][$i][‘ssl_verify’]`
This configuration disables server certificate verification. Use with
caution.

When the database server is using a local connection or private network and SSL can not be configured
you can use :config:option:`$cfg[‘MysqlSslWarningSafeHosts’]` to explicitly list the hostnames that are considered secure.

.. seealso::

    :ref:`example-google-ssl`,
    :ref:`example-aws-ssl`,
    :config:option:`$cfg['Servers'][$i]['ssl']`,
    :config:option:`$cfg['Servers'][$i]['ssl_key']`,
    :config:option:`$cfg['Servers'][$i]['ssl_cert']`,
    :config:option:`$cfg['Servers'][$i]['ssl_ca']`,
    :config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
    :config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
    :config:option:`$cfg['Servers'][$i]['ssl_verify']`

Various display setting¶

$cfg['RepeatCells']

Repeat the headers every X cells, or 0 to deactivate.

$cfg['QueryHistoryDB']
$cfg['QueryHistoryMax']

If $cfg['QueryHistoryDB'] is set to true, all your
Queries are logged to a table, which has to be created by you (see
$cfg['Servers'][$i]['history']). If set to false, all your
queries will be appended to the form, but only as long as your window is
opened they remain saved.

When using the JavaScript based query window, it will always get updated
when you click on a new table/db to browse and will focus if you click on
Edit SQL after using a query. You can suppress updating the
query window by checking the box Do not overwrite this query
from outside the window
below the query textarea. Then you can browse
tables/databases in the background without losing the contents of the
textarea, so this is especially useful when composing a query with tables
you first have to look in. The checkbox will get automatically checked
whenever you change the contents of the textarea. Please uncheck the button
whenever you definitely want the query window to get updated even though
you have made alterations.

If $cfg['QueryHistoryDB'] is set to true you can
specify the amount of saved history items using
$cfg['QueryHistoryMax'].

$cfg['BrowseMIME']

Enable Transformations.

Zero configuration

In many cases, this database structure can be automatically created and
configured. This is called “Zero Configuration” mode and can be particularly
useful in shared hosting situations. “Zeroconf” mode is on by default, to
disable set :config:option:`$cfg[‘ZeroConf’]` to false.

The following three scenarios are covered by the Zero Configuration mode:

Добавляем динамичности

Теперь настало время создать файлы проекта:

reg.php

log.php

enter.php

header.php

Начнем с последнего. Он поможет нам облегчить весь процесс создания формы авторизации на PHP. В него мы запишем используемую всеми тремя формами часть разметки HTML – раздел header:

Сохраните этот файл на сервере как header.php. Затем создайте все перечисленные выше файлы, но уже без раздела header. А вместо него вверху вставьте строку:

Теперь, если открыть любую из выше перечисленных веб-страниц проекта и просмотреть в браузере их код, то увидите, что раздел header на месте. И все потому, что при вызове любой из страниц его разметка динамически добавляется из одноименного файла.

Такую динамичность можно реализовать для любого модуля сайта. Даже в форме для создания папки на сервере PHP.

Настраиваем регистрацию

В файле reg.php располагается весь функционал для регистрации пользователей: форма и обработчик введенных в нее данных. При использовании связки PHP MySQL для создания и обработки форм значения всех полей, заполняемых пользователем и передаваемых на обработку, нужно предварительно «очистить».

На основе данного примера можно реализовать скрипт создания формы редактирования данных (update PHP). Но это уже немного из другой «оперы» :)

Сверху нее отображаются все системные сообщения. При успешной регистрации можно добавить переход на страницу приветствия (enter.php). Для этого замените строку PHP:

Код файла enter.php:

Думаю, на сегодня достаточно. На основе приведенного примера вы легко сможете создать скрипт авторизации. Возможно, у вас получатся более роскошные формы для сайта :)

Скрипт проверки авторизации

Сама авторизация представляет собой создание глобальной переменной $_SESSION. То есть если эта глобальная переменная есть, то пользователь авторизован, стало быть скрипт должен проверить, создана ли она ( глобальная переменная ). Если да то ничего не делать, если же нет, то перекинуть на файл login.php.

Перед тем как вызывать глобальную переменную $_SESSION, необходимо стартовать сессию, а именно прописать session_start(); Если этого не сделать, то глобальная переменная $_SESSION просто не будет работать!

В общем вот скрипт который необходимо вставить сразу после подключения к БД в index.php

Так как значение глобальной переменной $_SESSION переносится в переменную $logSESS, то нам необходимо пресечь попытку создать эту переменную ( $logSESS ) иными способами ( я имею введу предотвратить создание этой переменной с помощью GET и POST запроса ). Именно эту функцию выполняют первые две строчки скрипта.

Далее мы стартуем сессию, и проверяем существует ли глобальная переменная $_SESSION. Если нет, то переносим пользователя на страницу авторизации.

Создание простой системы регистрации пользователей на php и mysql

*Наведите курсор мыши для приостановки прокрутки.

Создание системы регистрации – это большая работа. Вам приходится писать код, который осуществляет валидацию email-адресов, отправляет сообщение на почту с подтверждением регистрации, а также осуществляет валидацию остальных полей формы, и много ещё всего.

И даже после того как вы всё это напишите, пользователи будут регистрироваться неохотно, т.к. это требует определённых усилий с их стороны.

В этом уроке, мы создадим очень простую систему регистрации, которая не требует и не хранит паролей вообще! Результат будет легко изменить и добавить к уже существующему PHP-сайту. Хотите выяснить, как это работает? Читайте ниже.

Скачать исходники к уроку

Вот как наша супер простая система будет работать:

– Мы скомбинируем форму авторизации и регистрацию. В этой форме будет поле для ввода email-адреса и кнопка регистрации;
– При заполнении поля email-адресом, по нажатию на кнопку регистрации будет создана запись о новом пользователе, но только в том случае, если введённого email-адреса не было найдено в базе данных.

После этого создаётся некий случайный уникальный набор символов (токен), который отправляется на указанную пользователем почту в виде ссылки, которая будет актуальна в течение 10 минут;
– По ссылке пользователь переходит на наш сайт. Система определяет наличие токена и авторизует пользователя;

Преимущества такого подхода:

– Не нужно хранить пароли и осуществлять валидацию полей;
– Нет необходимости в восстановлении пароля, секретных вопросов и т.д.;
– С момента как пользователь зарегистрировался/авторизовался вы можете всегда быть уверены, что этот пользователь будет в вашей зоне доступа (что email-адрес является истинным);
– Невероятно простой процесс регистрации;

Недостатки:

– Безопасность аккаунта пользователя. Если кто-то имеет доступ к почте пользователя, он может авторизоваться.
– Email не защищён и может быть перехвачен. Имейте в виду, что этот вопрос актуален и в случае, когда пароль был забыт и его необходимо восстановить, или в любой системе авторизации, которая не использует HTTPS для передачи данных (логин/пароль);
– Пока вы настроите как нужно почтовый сервер, существует шанс, что сообщения со ссылками на авторизацию будут попадать в спам;

Сравнивая преимущества и недостатки нашей системы, можно сказать, что система имеет высокое юзабилити (максимально удобна для конечного пользователя) и, в то же время, имеет невысокий показатель безопасности.

Так что использовать её предлагается для регистраций на форумах и сервисах, которые не работают с важной информацией.

Как пользоваться этой системой

В случае, когда вам нужно просто использовать систему для авторизации пользователей на вашем сайте, и вам не хочется разбирать данный урок по косточкам, вот что вам нужно сделать:

– Вам нужно скачать исходники, приложенные к уроку
– В архиве найти файл tables.sql Импортируйте его в вашу базу данных используя опцию импорта в phpMyAdmin. Альтернативный способ: открыть этот файл через текстовый редактор, скопировать SQL запрос и выполнить его;
– Открыть includes/main.php и заполнить настройки связи с вашей базой данных (указать пользователя и пароль для связи с базой а также хост и имя базы). В этом же файле, вы также должны указать email, который будет использован в качестве оригинального адреса для сообщений отправляемых системой. Некоторые хосты блокируют исходящие мейлы пока в форме не будет указан настоящий email адрес, который был создан из панели управления хостом, так что укажите реальный адрес;
– Загрузите все файлы index.php, protected.php и папки assets и includes через FTP на ваш хост;
– Добавьте код ниже на каждую PHP-страницу, где нужно отобразить форму авторизации;


require_once 'includes/main.php';

$user = new User();

if(!$user-&gtloggedIn()){
    redirect('index.php');
}

– Готово!

Для тех же, кому интересно, как это всё работает – вперёд к чтению ниже!

HTML

Первый шаг – написание HTM- кода формы авторизации. Данный код располагается в файле index.php. Этот файл также содержит PHP-код, обрабатывающий данные формы и другие полезные функции системы авторизации. Узнать об этом больше можно в разделе ниже, посвящённом обзору PHP кода.

index.php


<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8"/>
        <title>Tutorial: Super Simple Registration System With PHP & MySQL</title>

        <!-- Главный CSS файл -->
        <link href="assets/css/style.css" rel="stylesheet" />

        <!--[if lt IE 9]>
        <script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
    </head>

    <body>

        <form id="login-register" method="post" action="index.php">

            <h1>Login or Register</h1>

            <input type="text" placeholder="[email protected]" name="email" 
            autofocus />
            <p>Enter your email address above and we will send <br />you a login link.</p>

            <button type="submit">Login / Register</button>

            <span></span>

        </form>

        <!-- Подключение яваскрипт -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script src="assets/js/script.js"></script>

    </body>
</html>

В головной секции (между тегами <head> и </head>) я подключил основные стили (в этом уроке они не разбираются, поэтому вы можете посмотреть их сами. Папка assets/css/style.css). До закрывающего тега </body> я подключил библиотеку jQuery и файл script.js, который мы напишем и разберём чуть ниже.

Configuration — phpMyAdmin 5.1.4 documentation

Форма авторизации/регистрации

JavaScript

jQuery отслеживает состояние кнопки “Зарегистрироваться/авторизоваться” с помощью функции e.preventDefault() и отправляет AJAX-запросы. В зависимости от ответа сервера, выводит то или иное сообщение и определяет дальнейшие действия/

assets/js/script.js


$(function(){

var form = $('#login-register');

form.on('submit', function(e){

if(form.is('.loading, .loggedIn')){
    return false;
    }

    var email = form.find('input').val(),
    messageHolder = form.find('span');

        e.preventDefault();

        $.post(this.action, {email: email}, function(m){

            if(m.error){
                form.addClass('error');
                messageHolder.text(m.message);
            }
            else{
                form.removeClass('error').addClass('loggedIn');
                messageHolder.text(m.message);
            }
        });

    });

    $(document).ajaxStart(function(){
        form.addClass('loading');
    });

    $(document).ajaxComplete(function(){
        form.removeClass('loading');
    });
});

Класс .loading был добавлен в форму для отображения текущего состояния AJAX-запроса ( это стало возможным благодаря методам ajaxStart()) и ajaxComplete(), которые вы сможете найти ближе к концу файла).

Этот класс показывает крутящийся анимированный gif-файл (как бы намекающий нам на то, что запрос обрабатывается), и также выступает как флаг, предотвращающий повторную отправку формы (когда кнопка зарегистрироваться была уже однажды нажата). Класс .loggedIn – это другой флаг, – устанавливается тогда, когда был отправлен email. Этот флаг моментально блокирует любые дальнейшие действия с формой.

Схема базы данных

Наша невероятно простая система регистрации использует 2 MySQL таблицы (SQL-код находится в файле tables.sql). Первая хранит данные об аккаунтах пользователей. Вторая хранит информацию о количестве попыток входа.

Configuration — phpMyAdmin 5.1.4 documentation

Схема таблицы пользователей.

Система не использует паролей, что видно на схеме. На ней же можно увидеть колонку token с токенами, соседствующую с колонкой token_validity. Токен устанавливается как только пользователь подключается к системе, задаёт свой email для отправки сообщения (чуть подробнее об этом в следующем блоке). Колонка token_validity устанавливает время на 10 минут позже, после которого токен перестаёт быть актуальным.

Каждый раз, когда кто-то пытается авторизоваться, появляется новая запись во второй таблице (reg_loggin_attempt). Как вы могли заметить, в нашем PHP-коде существует ограничение по количеству попыток авторизации в зависимости от IP-адреса.

Ограничение установлено на 10 попыток авторизации в течение 10 минут и на 20 попыток в течение часа. Большее число попыток приведёт к блокировке IP-адреса, до тех пор, пока не пройдёт необходимое время (10 минут или час соответственно).

Configuration — phpMyAdmin 5.1.4 documentation

Схема таблицы, считающая количество попыток авторизации.

В обоих таблицах IP-адрес хранится в обработанном виде, с помощью функции ip2long в поле типа integer.

PHP

Теперь мы можем написать немножко PHP-кода. Основной функционал системы возложен на класс User.class.php, который вы можете видеть ниже.

Данный класс активно использует idorm (docs), эти библиотеки являются минимально необходимыми инструментами, для работы с базами данных. Он обрабатывает доступ к базе данных, генерацию токенов и их валидацию. Он представляет собой простой интерфейс, позволяющий легко подключить систему регистрации к вашему сайту, если он использует PHP.

User.class.php


	class User{

    // Частный ORM случай
    private $orm;

     /**
     * Найти пользователя по токену. Только валидные токены, приняты к рассмотрению. Токен генерируется только на 10 минут с того момента как был создан
     *  @param string $token. Это искомый токен
     *	@return User. Вернуть значение функции User
     */

    public static function findByToken($token){

        // найти токен в базе и убедиться, что установлен корректный временной штамп 
        $result = ORM::for_table('reg_users')
                        ->where('token', $token)
                        ->where_raw('token_validity > NOW()')
                        ->find_one();

        if(!$result){
            return false;
        }

        return new User($result);
    }

     /**
     * Авторизовать или зарегистрировать пользователя
     * @param string $email. Пользовательский email-адрес
     *	@return User
     */

    public static function loginOrRegister($email){

        // Если такой пользователь уже существует, вернуть значение функции User от заданного email-адреса хранимого в базе

        if(User::exists($email)){
            return new User($email);
        }

        // В противном случае создать нового пользователя в базе и вернуть значение функции User::create от указанного email

        return User::create($email);
    }

     /**
     * Создать нового пользователя и сохранить в базу
     * @param string $email. Пользовательский email-адрес
     * @return User
     */

    private static function create($email){

        // Записать нового пользователя и вернуть результат функции
        User от этих значений

        $result = ORM::for_table('reg_users')->create();
        $result->email = $email;
        $result->save();

        return new User($result);
    }

     /**
     * Проверить, существует ли такой пользователь в базе и вернуть булево значение переменной
     * @param string $email. Пользовательский email-адрес
     * @return boolean
     */

    public static function exists($email){

        // Существует ли пользователь в базе?
        $result = ORM::for_table('reg_users')
                    ->where('email', $email)
                    ->count();

        return $result == 1;
    }

    /**
     * Создать новый пользовательский объект
     * @param экземпляр $param ORM , id, email or 0
     * @return User
     */


    public function __construct($param = null){

        if($param instanceof ORM){

            // ORM проверка пройдена
            $this->orm = $param;
        }
        else if(is_string($param)){

            // Проверка на email пройдена
            $this->orm = ORM::for_table('reg_users')
                            ->where('email', $param)
                            ->find_one();
        }
        else{

            $id = 0;

            if(is_numeric($param)){
                // идентификатору пользователя передаётся значение переменной $param
                $id = $param;
            }
            else if(isset($_SESSION['loginid'])){

                // В противном случае смотри сессию
                $id = $_SESSION['loginid'];
            }

            $this->orm = ORM::for_table('reg_users')
                            ->where('id', $id)
                            ->find_one();
        }

    }

    /**
     * Сгенерировать новый SHA1 токен авторизации, записывает в базу и возвращает его значение
     * @return string
     */

    public function generateToken(){
        // Сгенерировать токен для авторизованного пользователя и сохранить его в базу

        $token = sha1($this->email.time().rand(0, 1000000));


        // Сохранить токен в базе
        // И пометить его, что он актуален только в течение 10 следующих минут

        $this->orm->set('token', $token);
        $this->orm->set_expr('token_validity', "ADDTIME(NOW(),'0:10')");
        $this->orm->save();

        return $token;
    }

    /**
     * Авторизовать пользователя
     * @return void
     */

    public function login(){

        // Отметить пользователя, как авторизованного
        $_SESSION['loginid'] = $this->orm->id;

        // Обновить значение поля базы last_login
        $this->orm->set_expr('last_login', 'NOW()');
        $this->orm->save();
    }

    /**
     * Уничтожить сессию и разлогинить пользователя
     * @return void
     */

    public function logout(){
        $_SESSION = array();
        unset($_SESSION);
    }

    /**
     * Проверка, заходил ли пользователь
     * @return boolean
     */

    public function loggedIn(){
        return isset($this->orm->id) && $_SESSION['loginid'] == $this->orm->id;
    }

    /**
     * Проверка является ли пользователь администратором
     * @return boolean
     */

    public function isAdmin(){
        return $this->rank() == 'administrator';
    }

    /**
     * Найти тип пользователя, может быть либо administrator либо regular
     * @return string
     */

    public function rank(){
        if($this->orm->rank == 1){
            return 'administrator';
        }

        return 'regular';
    }

    /**
     * Метод позволяющий получить приватную информацию пользователя в 
     *качестве свойств объекта User
     * @param string $key Имя свойства, получающего доступ 
     * @return mixed
     */

    public function __get($key){
        if(isset($this->orm->$key)){
            return $this->orm->$key;
        }

        return null;
    }
}

Токены генерируются с помощью SHA1 алгоритма и сохраняются в базе данных. Я использую функции времени MySQL, дабы задать 10-минутное ограничение актуальности токена.

Когда токен проходит процедуру валидации, мы напрямую говорим обработчику, что мы рассматриваем только токены, у которых ещё не истёк срок годности, хранимый в столбце token_validity.

Обратите внимание, что я использую волшебный метод __get библиотеки docs в конце файла, чтобы перехватить доступ к свойствам объекта User.

Благодаря этому становится возможным получить доступ к информации, хранящейся в базе, благодаря свойствам $user->email, $user->token и др. В следующем фрагменте кода рассмотрим для примера, как использовать эти классы.

Configuration — phpMyAdmin 5.1.4 documentation

Защищённая страница

Ещё один файл, хранящий полезный и необходимый функционал – это файл functions.php. Здесь есть несколько так называемых хелперов – функций-помощников, которые позволяют создавать более чистый и читабельный код в других файлах.

functions.php


	function send_email($from, $to, $subject, $message){

    // Хелпер, отправляющий email
    $headers  = 'MIME-Version: 1.0' . "rn";
    $headers .= 'Content-type: text/plain; charset=utf-8' . "rn";
    $headers .= 'From: '.$from . "rn";

    return mail($to, $subject, $message, $headers);
}

function get_page_url(){

    // Определить URL PHP-файла

    $url = 'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'];

    if(isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] != ''){
        $url.= $_SERVER['REQUEST_URI'];
    }
    else{
        $url.= $_SERVER['PATH_INFO'];
    }

    return $url;
}

function rate_limit($ip, $limit_hour = 20, $limit_10_min = 10){

    // Количество попыток входа за последний час по этому IP-адресу
    $count_hour = ORM::for_table('reg_login_attempt')
                    ->where('ip', sprintf("%u", ip2long($ip)))
                    ->where_raw("ts > SUBTIME(NOW(),'1:00')")
                    ->count();

    //  Количество попыток входа за последние 10 минут по этому IP-адресу
    $count_10_min =  ORM::for_table('reg_login_attempt')
                    ->where('ip', sprintf("%u", ip2long($ip)))
                    ->where_raw("ts > SUBTIME(NOW(),'0:10')")
                    ->count();

    if($count_hour > $limit_hour || $count_10_min > $limit_10_min){
        throw new Exception('Too many login attempts!');
    }
}

function rate_limit_tick($ip, $email){

    // Создать новую запись в таблице, считающей количество попыток входа
    $login_attempt = ORM::for_table('reg_login_attempt')->create();

    $login_attempt->email = $email;
    $login_attempt->ip = sprintf("%u", ip2long($ip));

    $login_attempt->save();
}

function redirect($url){
    header("Location: $url");
    exit;
}

Функции rate_limit и rate_limit_tick следят за количеством попыток авторизации за истёкший период времени с момента первой попытки. Попытка входа записывается в базе в столбец reg_login_attempt. Эти функции вызываются когда происходит обработка и отправка данных формы как вы можете видеть из следующего фрагмента кода.

Код ниже взят из файла index.php и он обрабатывает отправку формы. Он возвращает JSON-ответ, который, в свою очередь, обрабатывается jQuery в файле assets/js/script.js, который мы уже разбирали ранее.

index.php


try{

    if(!empty($_POST) && isset($_SERVER['HTTP_X_REQUESTED_WITH'])){

        // Output a JSON header

        header('Content-type: application/json');

        // Является ли этот email-адрес валидным
        if(!isset($_POST['email']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
            throw new Exception('Please enter a valid email.');
        }

        // Проверка. Позволено ли пользователю авторизоваться, не превысил ли он количество допустимых подключений? (файл functions.php для большей информации)
        rate_limit($_SERVER['REMOTE_ADDR']);

        // Записать эту попытку авторизации
        rate_limit_tick($_SERVER['REMOTE_ADDR'], $_POST['email']);

        // Отправить письмо пользователю
        $message = '';
        $email = $_POST['email'];
        $subject = 'Your Login Link';

        if(!User::exists($email)){
            $subject = "Thank You For Registering!";
            $message = "Thank you for registering at our site!nn";
        }

        // Попытка авторизовать или зарегистрировать пользователя
        $user = User::loginOrRegister($_POST['email']);

        $message.= "You can login from this URL:n";
        $message.= get_page_url()."?tkn=".$user->generateToken()."nn";

        $message.= "The link is going expire automatically after 10 minutes.";

        $result = send_email($fromEmail, $_POST['email'], $subject, $message);

        if(!$result){
            throw new Exception("There was an error sending your email. Please try again.");
        }

        die(json_encode(array(
            'message' => 'Thank you! We've sent a link to your inbox. Check your spam folder as well.'
        )));
    }
}
catch(Exception $e){

    die(json_encode(array(
        'error'=>1,
        'message' => $e->getMessage()
    )));
}

После успешной авторизации/регистрации код выше отправит пользователю ссылку для авторизации. Токен становится доступным, т.к. он передаётся в качестве переменной в генерируемой ссылке методом $_GET с маркером tkn

Переход по полученной ссылке послужит триггером для запуска кода ниже:

index.php


	if(isset($_GET['tkn'])){

    // Является ли этот токен валидным для авторизации?
    $user = User::findByToken($_GET['tkn']);

    if($user){

        // Да, является. Осуществить редирект на защищённую страницу
        $user->login();
        redirect('protected.php');
    }

    // Нет, токен не валидный. Осуществить редирект, на страницу с формой авторизации/регистрации
    redirect('index.php');
}

Вызов


$user->login()

создаст необходимые переменные для сессии, так что пользователь, просматривая последующие страницы сайта, будет всё время оставаться авторизованным.

Похожим образом устроена и обработка функции на выход из системы.

index.php


    if(isset($_GET['logout'])){

    $user = new User();

    if($user->loggedIn()){
        $user->logout();
    }

    redirect('index.php');
}

В конце кода, я снова поставил редирект на index.php, таким образом параметр ?logout=1 передаваемый посредством URL не требуется.

Наш файл index.php требует доп. защиты – мы не хотим, чтобы люди, которые когда-либо однажды авторизовались в системе опять видели форму регистрации. Для этих целей, мы используем метод $user->loggedIn().

index.php


$user = new User();

if($user->loggedIn()){
    redirect('protected.php');
}

Наконец-то, вот кусок кода, позволяющий защитить страницы вашего сайта и сделать её доступной только после авторизации.

protected.php


// Чтобы защитить каждую страницу на вашем сайте подключите к ней файл
// main.php и создайте новый объект User. Вот как это просто!

require_once 'includes/main.php';

$user = new User();

if(!$user->loggedIn()){
    redirect('index.php');
}

После этой проверки можете быть уверенными, что пользователь был успешно авторизован. Вы также можете получить доступ к хранимой информации в базе с помощью свойств объекта $user. Для вывода email-а пользователя и его статуса используйте этот код:


echo 'Your email: '.$user->email;
echo 'Your rank: '.$user->rank();

Метод rank() используется здесь потому что в базе обычно хранятся номера (0 для обычного пользователя, 1 для администратора) и нам нужно преобразовать эти данные в статусы, к которым они относятся, в чём нам и помогает этот метод.

Чтобы сделать из обычного пользователя администратора, просто отредактируйте пользовательскую запись через phpMyAdmin (или любую другую программу, позволяющую управлять базами данных). Статус администратора не даёт каких-либо привилегий, в данном примере на странице будет выведено, что вы администратор – и всё.

А вот что с этим делать – остаётся уже на ваше усмотрение, вы можете сами написать и составить код, задающий определённые привилегии и возможности для администраторов.

Мы закончили!

С этой невероятно супер квази простой формой мы закончили! Вы можете использовать её в ваших PHP-сайтах, это достаточно просто. Также вы можете модифицировать её под себя и сделать её такой, как вы хотите.

Материал подготовил Денис Малышок специально для сайта vhod-v-lichnyj-kabinet.ru

P.S. Хотите двигаться дальше в освоении PHP и ООП? Обратите внимание на премиум-уроки по различным аспектам сайтостроения, включая программирование на PHP, а также на бесплатный курс по созданию своей CMS-системы на PHP с нуля с использованием ООП:

Configuration — phpMyAdmin 5.1.4 documentation

Configuration — phpMyAdmin 5.1.4 documentation

Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!

Смотрите также:

Наверх

Final thoughts

That all you need to know how to create registration and login system in PHP with MySQL database. Furthermore, we create a registration and login form. Moreover, we create a MySQL connection file to establish a database connection. Thus we create a complete login system with interactive design.

We hope you have found this article helpful. Let us know your questions or feedback if any through the comment section in below. You can subscribe our newsletter and get notified when we publish new WordPress articles for free. Moreover, you can explore here other JavaScript related articles.

Icon made by Kmg Design

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *