Авторизация на Delphi (продолжение)

Авторизация в Delphi

В прошлой статье Авторизация на Delphi мы рассмотрели один из способов организации появления окна авторизации пользователя. Мы рассматривали этот вопрос в отношении приложения многодокументного типа. В этой статье акцент будет сделан на однодокументное приложение SDI типа.

Что такое SDI и MDI типы приложений?

SDI-приложение — это приложение однодокументного типа (Single document interface). Это означает, что все окна приложения не принадлежат какому-то общему окну, а открываются сами по себе и в диспетчере задач Windows каждое открытое окно будет высвечиваться на своей вкладке. Примером такого типа приложений является MS Word, MS Excel и другие программы из пакета MS Office.

Здесь каждый созданный файл (документ Word или книга Excel) будут открываться в отдельном окне и выглядеть при этом как отдельно открытый экземпляр приложения, хотя на самом деле это и не так. В самых ранних версиях эти приложения была MDI типа.

MDI-приложение — это многодокументный тип приложения (multiple document interface). Интерфейс MDI типа подразумевает одно главное окно приложения, в котором будут открываться все остальные окна. Примером такого приложения может служить CorelDraw или Adobe Photoshop, Adobe Reader...

Схема авторизации пользователя

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

Итак, авторизация может быть организована следующим образом. Все пользователи должны быть где то учтены. очень удобно для этих целей использовать базу данных. Да и вообще, если приложение разрабатывается для работы с базами данных (для чего чаще всего и используется Delphi), то тогда на самом деле стоит хранить всю информацию о пользователях именно в базе данных.

Так как я люблю работать с MySQL я буду показывать скрины на его примере. Но на других СУБД, таких как MS SQL Server, MS Access и других способ организации точно такой же.

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

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

Тогда схема таблиц для авторизации пользователей будет выглядеть так:

Схема БД для авторизации пользователя
Схема БД для авторизации пользователя

Мы видим две родительские таблицы (Роли и Пользователи) и одну дочернюю — Аккаунты. Естественно, что связь между Роли и Аккаунты, а также Пользователи и Аккаунты будет как один-ко-многим. Почему? Потому что один и тот же пользователь, как я говорил выше в нашем примере может иметь несколько ролей. Ровно как и одна и та же роль может быть назначена разным пользователям. Это называется отношение много-ко многим.

Отношение много-ко-многим присутствует между таблицами Роли и Пользователи. Но такое отношение не назначается напрямую, а решается с помощью промежуточной (объединяющей таблицы). В нашем случае это таблица Аккаунты.

Теперь давайте вернемся к непосредственной авторизации на Delphi и рассмотрим вопрос о том, как сделать авторизацию пользователя.

Форма авторизации пользователя

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

Форма авторизации пользователя в конструкторе форм
Форма авторизации пользователя в конструкторе форм

Обычно модуль, описывающий форму авторизации пользователя я называю login.pas, форму именую как frmLogin. Задавать корректные имена очень удобно. Не следует оставлять элементы с именами по умолчанию.

Также в этой форме присутствует раскрывающийся список (TCombobox) и текстовое поле (TEdit), две кнопки класса TPanel и один компонент доступа к данным типа (TadoQuery).

В данном примере кнопки представлены компонентом TPanel, а не TButton. Это сделано для того, чтобы мне было легче придать интерфейсу тот вид, которого я хотел добиться. Эти вещи можно сделать и по другому, а именно можно использовать стили и тогда можно использовать обычные кнопки, но назначать им стили отображения. Это другой способ. Но это не тема данной статьи, а небольшое отступление, поэтому больше здесь мы это затрагивать не будем.

Собственно весь дальнейший процесс описан в предыдущей статье Авторизация на Delphi. Здесь я покажу только то, как заполняется список из логинов, потому что в предыдущей статье я не описывал это...

Для заполнения списка логинами я использую компонент набора данных TadoQuery с именем adoLogin.

В свойстве SQL данного компонента я использую запрос:

SELECT
    роли.Код_роли,
    роли.Роль,
    пользователи.Код_пользователя,
    пользователи.ФИО,
    аккаунты.Код_аккаунта,
    аккаунты.Логин,
    аккаунты.Пароль
FROM
    роли
    INNER JOIN аккаунты ON аккаунты.Код_роли = роли.Код_роли
    INNER JOIN пользователи ON аккаунты.Код_пользователя = пользователи.Код_пользователя
WHERE аккаунты.Статус = 'Действующий'

В событии onCreate (когда у нас создается форма для авторизации пользователя) мы пишем следующий код:

procedure TfrmLogin.FormCreate(Sender: TObject);
var
  KolZap: integer;
  TekZap: integer;
  i: integer; // Счетчик
begin
     //Прячем все пункты меню
     frmMDI.mnuAdmin.Visible:=false;
     frmMDI.mnuLogin.Visible:=false;
     frmMDI.mnuTovar.Visible:=false;
     frmMDI.mnuKont.Visible:=false;
     frmMDI.mnuDv.Visible:=false;
     frmMDI.mnuAnalis.Visible:=false;
     //Подключаемся к Таблице Логины
     adoLogin.Open;
     //Заполняем логинами раскрывающийся список
     cboLogin.Clear;
     KolZap:=adoLogin.RecordCount;
     adoLogin.First;
     TekZap:=adoLogin.RecNo;
     for i:=TekZap to KolZap do
     begin
       cboLogin.Items.Add(adoLogin.fieldbyname('Логин').AsString);
       adoLogin.Next;
     end;
    //Сортируем список
    cboLogin.Sorted:=true;
   //Ставим первое значение в списке по умолчанию
   cboLogin.ItemIndex:=0;
end;

Теперь после запуска приложения и появления окна авторизации раскрывающийся список Имя пользователя будет заполнен логинами из набора данных, полученного на основе запроса на объединение данных из трех таблиц (Роли, Пользователи и Аккаунты).

В кнопке Вход нужно прописать такой код:

procedure TfrmLogin.pnlFirstGroupClick(Sender: TObject);
var
    sTiplist: TStrings;
    sTiplistUser: String;
    sPassword: string;
begin
    sLogin:=cboLogin.Text;
    sPassword:=trim(txtPassword.Text);
    //Теперь проверяем пароль пользователя
    adoLogin.First;//Ставим указатель на первую запись таблицы
    adoLogin.Locate('Логин', sLogin,[]);// Находим в таблице запись с выбранным логином
    if adoLogin.fieldbyname('Пароль').AsString = sPassword then //Если пароль совпадает с введенным, то
    begin
        //Заменяем пробелы на подчеркивание, потому что в строковом перечислении
        //пробелы не работают пробелы
        sTipUser:=adoLogin.fieldbyname('Роль').AsString;
        sTiplistUser:=StringReplace(adoLogin.fieldbyname('Роль').AsString, ' ', '_',[rfReplaceAll, rfIgnoreCase]);
        sTiplist:=TStrings(GetEnumValue(TypeInfo(TStrings), sTiplistUser));
        case sTiplist of
             Администраторы:
             begin
                 frmMDI.mnuAdmin.Visible:=true;
                 frmMDI.mnuLogin.Visible:=true;
                 frmMDI.mnuTovar.Visible:=true;
                 frmMDI.mnuKont.Visible:=true;
                 frmMDI.mnuDv.Visible:=true;
                 frmMDI.mnuAnalis.Visible:=true;
             end;
             Менеджеры:
             begin
                 frmMDI.mnuAdmin.Visible:=false;
                 frmMDI.mnuLogin.Visible:=true;
                 frmMDI.mnuTovar.Visible:=true;
                 frmMDI.mnuKont.Visible:=true;
                 frmMDI.mnuDv.Visible:=true;
                 frmMDI.mnuAnalis.Visible:=true;
             end;
             Кладовщики:
             begin
                 frmMDI.mnuAdmin.Visible:=false;
                 frmMDI.mnuLogin.Visible:=true;
                 frmMDI.mnuTovar.Visible:=false;
                 frmMDI.mnuKont.Visible:=false;
                 frmMDI.mnuDv.Visible:=true;
                 frmMDI.mnuAnalis.Visible:=false;
             end;
        end;
        //Раз пароль подошел, то получаем из записи остальные
        //характеристики пользователя
        iIDUser:=adoLogin.fieldbyname('Код_аккаунта').AsInteger;
        sFIOUser:=adoLogin.fieldbyname('ФИО').AsString; //Присваиваем ФИО пользователя, вошедшего в систему из набора
        //Устанавливаем для главной формы заголовок
        frmMDI.Caption:='Мониторинг складского учета торговой сети - '+'Пользователь: '+sLogin+'      '+'ФИО: '+sFIOUser+'      '+'Роль: '+sTipUser;
        frmMDI.AlphaBlendValue:=255;//Делаем главную форму видимой
        Close;//и закрываем окно авторизации
    end else //Если введенный пароль не совпал с тем, который в записи, то
    begin
        MessageCreate(Left,Top,Height,Width,'Пароль не верный! Обратитесь к администратору системы!');
    end;
end;

Здесь MessageCreate — это моя пользовательская процедура создания окна сообщения. Вы можете вместо нее использовать, например стандартную функцию MessageBox или свою собственную форму, разработанную в Delphi.

Это был все также пример для MDI-приложения. Его я показал для того, что бы рассмотреть идею общей организации схемы авторизации пользователя на Delphi.

Хочу также отметить, что в данном примере всех пользователей создает администратор. Он же и назначает пользовательский пароль. Здесь пользователь не создает учетную запись самостоятельно. Это достаточно распространенный метод в бизнес-приложениях. После создания учетной записи, администратор отдает новому пользователю парольную карточку.

Форма авторизации пользователя в SDI-приложении на Delphi

Все, что будет написано ниже справедливо как для библиотеки VCL, так и для кроссплатформенной библиотеки FMX.

В автозапуске оставляем только основную форму. Допустим называется она frmSDI. Форму frmLogin убираем из автозапуска. В форме frmSDI объявляем глобальную переменную: zapusk: boolean;

В событии OnCreate формы frmSDI этой переменной присваиваем True.

procedure TfrmSDI.FormCreate(Sender: TObject);
begin
  zapusk:=true;
end;

В событии OnShow формы frmSDI пишем:

procedure TfrmSDI.FormShow(Sender: TObject);
begin
  if Zapusk=true then
  begin
    Application.CreateForm(TfrmLogin, frmLogin);
    frmLogin.Show;
    frmSDI.Hide;
  end;
end;

В событии OnCreate формы frmLogin пишем:

procedure TfrmLogin.FormCreate(Sender: TObject);
begin
  Zapusk:=false;
end;

В событии OnDestroy формы frmLogin пишем:

procedure TfrmLogin.FormDestroy(Sender: TObject);
begin
  zapusk:=true;
end;

Сама же форма авторизации пользователя (frmLogin) , будет точно такой же, как и в случае с приложением MDI-типа. Итак, мы рассмотрели некоторые вопросы по созданию формы авторизации пользователей на Delphi. Надеюсь, что материал будет полезным для вас.

Понравилась статья? Поделиться с друзьями:
Блог Алексея Иванкова
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: