На главную >>>


Регистрация, авторизация и аутентификация пользователей. Cookie.

Для начала, чтобы не слишком пугаться (путаться), приведем определения:


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

Введение

Цель данного описания - показать программистам, как можно контролировать доступ пользователей к содержимому сайта. Эта проблема актуальна например, для посетителей форумов. Некоторая информация о пользователе, например, его имя, пароль, адрес его электронной почты может храниться на сервере. В некоторых случаях, сервер может высылать письма этому пользователю, однако другие пользователи не должны видеть этот адрес. Точно также другие пользователи не должны видеть (иметь доступ) к паролю этого пользователя.

В процессе регистрации пользователь сообщает серверу свое имя (в принципе любое буквосочетание) и пароль. Сервер их запоминает.

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

В процессе авторизации пользователь получает доступ к некоторым данным на сервере. При этом возможность доступа может зависеть от имени пользователя.

В данном описании мы будем полагать, что у программиста имеется доступ к сайту, где доступны для исполнения perl-скрипты.


Регистрация

Как же передать данные о пароле и имени пользователя на сервер?

Посмотрите на следующую форму:

Имя
Пароль

Она состоит из двух полей и кнопки. Исходный код этой формы написан ниже:

<form action="/cgi-bin/register.pl" method="POST">
<table>
<tr>
<td>Имя <input name="username" type=text size=50 maxsize=50></td>
<tr>       
<td>Пароль <input name="pass" type="password" size=50 maxsize=50></td>
</tr>
<td align=center><input type=submit value="OK">
</table>
</form>

В языке HTML есть объекты для ввода текста. Это поля <input type=text> Есть и кнопки для отправки данных, это <input type=submit> Все они обязаны находиться внутри объекта <form>. Из этого кода видно, что данные будут переданы скрипту под названием register,pl в виде двух переменных, username и pass. Это значит, что на нашем сервере, в папке cgi-bin, предназначенной для хранения скриптов, лежит некий скрипт, которому мы передадим имя и пароль, введенный пользователем.

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

Как же скрипт register,pl получает имя и пароль? Приведем начало этого скрипта. Учтите, что номера в начале строк не нужны, они написаны здесь лишь для удобства изложения.

1.  #!c:/perl/bin/perl -w
2.  use CGI;
3.  use strict;
4.  use Crypt::PasswdMD5;
5.
6.  my $query = new CGI; 
7.  my $username = $query->param('username');
8.  my $pass = $query->param('pass');
9.  my $passfile = ".pass";

Первые четыре строчки означают указание, где находится интерпретатор perl и какие библиотеки будут в этом скрипте использованы. В шестой строке создается объект $query типа CGI, с помощью которого будет происходить передача данных, печать информации и другие события, происходящие с браузером при работе. В седьмой строке из браузера извлекается информация о переданном имени пользователя (username), а в восьмой информация о его пароле. В девятой строке вводится название файла, где будут храниться зашифрованные пароли.

На всякий случай надо проверить, не существует ли уже пользователь с таким именем:

10. if(userExist($passfile, $username)){
11.     print "Content-Type: text/html\n\n";
12.     print "User exist, continuation not possible";
13.     print $query->end_html;
14.     exit (0);
15. }
Здесь вызывается некая функция userExist() которая возвращает единицу, если такой пользователь существует и ноль, если не существует. Эту функцию мы напишем позже. Если пользователь уже существует, надо напечатать на странице браузера, что продолжение невозможно и закончить работу скрипта, что и сделано в строках 10-15.

А если такого пользователя еще нет? Ну что ж, начнем шифровать.

10. my ($salt, $cryptedpassword);
11. $salt = rand(999999);
12. $cryptedpassword = unix_md5_crypt($pass, $salt);
13. open(PASSFILE, ">>$passfile");
14. print(PASSFILE "$username:$cryptedpassword\n");
15. print "Content-Type: text/html\n\n";
16. print "<p>User $username registered";
17. print $query->end_html;

Для шифрования пароля обычно используется функция unix_md5_crypt (строка 12). В качестве аргумента ей передают пароль и некоторое число, любое. Обычно для ээтого используют достаточно большое случайное число, которое сгенерировано в строке 11. К примеру, моего пользователя звали ggg и я выбрал себе пароль "123". У меня получился зашифрованный пароль такой: "$1$500884.5$mGHvyWSUJHB1FOPmnLQmt0". Не похоже на исходный, не правда ли?

Зашифрованный пароль (его еще называют хэшем пароля) дописывается в 13-14-ой строках в конец файла с паролями (он называется ".pass", как несложно догадаться из 9-ой строки программы). Перед ним записывается имя пользователя и знак двоеточия для того, чтобы можно было искать хеши паролей по именам пользователей. Дальше в строках 15-16 пишется в окно браузера, что регистрация пользователя прошла успешно, а в 17-ой строке скрипт завершает свою работу.

Итак, произошла регистрация. В конец файла с паролем добавлена строка:

ggg:$1$500884.5$mGHvyWSUJHB1FOPmnLQmt0

Аутентификация (login).

Когда зарегистрированный пользователь входит в систему, система должна проверить его имя и пароль на соответствие друг другу. Когда пользователь запрашивает некоторые данные, сервер должен определить, давать ли ему эти данные. Общение пользователя с сервером может включать в себя передачу целого ряда различного вида данных, которые пользователь получает в несколько приемов. Т.е. возникает проблема хранения информации о том, что пользователь вошел в систему. Эту информацию можно хранить в cookie-файлах на компьютере пользователя.

Приведем для начала форму для аутентификации (login'а). Она полностью аналогична форме для регистрации, отличие только в названии скрипта, которому передается информация о пароле и имени.

<form action="/cgi-bin/login.pl" method="POST">
<table>
<tr>
<td>Имя <input name="username" type=text size=50 maxsize=50></td>
<tr>       
<td>Пароль <input name="pass" type="password" size=50 maxsize=50></td>
</tr>
<td align=center><input type=submit value="OK">
</table>
</form>

Напишем скрипт login.pl, который будет вызваться при нажатии кнопки "ОК". В начале скрипта идет проверка правильности имени и пароля. Во первых имя и пароль не должны быть пустыми:

1.  #!c:/perl/bin/perl -w
2.  use CGI;
3.  use strict;
4.  use Digest::MD5 qw(md5_hex);
5.  use CGI::Cookie;

6.  my $query = new CGI; 
7.  my $username = $query->param('username');
8.  my $pass = $query->param('pass');
9.  my $passfile = ".pass";

10. if($username eq "" || $pass eq ""){
11.     print "Content-Type: text/html\n\n";
12.     print "Password or user name wrong";
13.     exit(0);
14. }

Здесь в строках 7-8 передаются параметры. В строке 10 происходит проверка на то, один из этих параметров пустой. И если есть пустой параметр, браузер выдает ответ: "Password or user name wrong", после чего завершает работу.

15. else{
16.    if(passwordCorrect($passfile, $username, $pass)){
17.        my $regedpass = getPassByName($passfile, $username);        
18.        my $fingerprint = md5_hex($regedpass);
19.        my $c1 = new CGI::Cookie(
20.            -name => "simple_gluk_guestbook",
21.            -expires => "+1y",
22.            -value => {
23.                         username => $username,
24.                         fingerprint => $fingerprint
25.                      }
26.        );
27.        print $query->redirect("view.pl", -cookie=>$c1);
28.     }
29.     else{
30.        print "Content-Type: text/html\n\n";
31.        print "Password incorrect";
32.        exit(0);
33.     }
34. } 

Если же пароль и имя не пустые, надо проверить их на правильность. Для этого мы используем функцию passwordCorrect, которую напишем позже. Эта функция берет на вход имя и пароль, а дальше сверяет их с тем паролем, что хранится в файле на сервере. Если пароль, введенный пользователем совпадает с паролем хранящемся на сервере, происходит установка cookie. Если не совпадает, пользователю выдается сообщение "Password incorrect".

Надеюсь, что вам стало все понятно.


На главную >>>