Главная страница


ru.perl

 
 - RU.PERL ----------------------------------------------------------------------
 From : Alexey Mahotkin                      2:5020/400     24 May 2003  18:42:29
 To : Nick Knutov
 Subject : Re: <none>
 -------------------------------------------------------------------------------- 
 
 >>>>> "NK" == Nick Knutov <Nick.Knutov@p27.f29.n5054.z2.fidonet.org> writes:
 
  NK> зы: в общем то надо сдалать автоpизацию и _идентификацию_ вдальнейшем
  NK> на некотоpом сайте несколько похожем на интеpнет магазин. Что еще для
  NK> этого посоветyете? 
 
 Во-первых, вот текст, призванный прочистить мозг относительно корректного
 использования терминов "аутентификация", "авторизация" и "идентификация":
 http://www.livejournal.com/talkread.bml?itemid=76975&journal=squadette
 
  NK> Т.е. чтобы после автоpизации какyю бы стpаницy
  NK> сайта юзеp не откpыл - надо чтобы сайт его yзнавал. И надо чтобы сайт
  NK> четко ловил когда юзеp отключился т.е. пpосто класть кyки как я
  NK> понимаю в данном слyчае недостаточно.  
 
 Это невозможно.  Браузер не присылает уведомления на сервер, когда
 закрывается окно.  Более того, я рекомендую если и сделать тайм-аут, то
 какой-нибудь типа месяца, потому что часто ты сидишь на странице магазина,
 параллельно лазия по интернету в поисках отзывов на товар.  Когда потом всё
 же решишь его купить, будет обломно заново делать логин при нажатии на
 клавишу "купить" ;) 
 
  NK> И естественно надо
  NK> пpедyсмотpеть что может быть несколько юзеpов с одного ip.
 В таблице юзеров есть два поля: имя и пароль.  Пароль обычно хранится
 не простым текстом, а "зашифрованный" с помощью crypt(), но мы пока не
 будем обращать на это внимания.
 
 Аутентификацией занимается модуль FooBar::Auth (где FooBar -- это
 название проекта, над которым я работаю в данный момент).
 
 Юзер вводит своё имя и пароль и жмёт на Submit.  Обработчик этой формы
 (FooBar::Login) просит FooBar::Auth проверить это имя и пароль
 (соответствующая функция называется check_password() и используется
 только при логине).
 
 FooBar::Auth лезет в таблицу юзеров и ищет там пароль, соответствующий
 указанному имени.  Если пароль не найден (такого имени нет), то
 FooBar::Auth возвращает ошибку.  Если пароль найден, но не совпадает с
 введенным в форме, то возвращается ошибка.  Само собой, оба раза
 ошибка звучит как "invalid login or password".  Hикогда нельзя делать
 две отдельных ошибки: "нет такого пользователя" и "неправильный
 пароль".
 
 Если пароль найден и совпадает с введенным, то FooBar::Auth возвращает
 OK.
 
 Модуль FooBar::Login, получив от FooBar::Auth ошибку, опять выдает
 страницу с логином и сообщением об ошибке.
 
 Если FooBar::Auth вернул OK, то FooBar::Login просит его сгенерировать
 аутентификационные куки.  В первой куке, которая называется "login",
 хранится имя пользователя.  Во второй куке, которая называется
 "password", хранится пароль, взятый из базы данных, и захэшированный с
 помощью md5.
 
 FooBar::Login помещает в заголовок ответа выданные ему куки и выдает
 редирект на индексную страницу.
 
 Теперь вся аутентификация проходит исключительно по кукам.
 
 Пусть теперь, например, юзер пошел на страницу с корзиной.  Обработчик
 этой страницы находится в FooBar::Basket.  Он использует две функции
 FooBar::Auth->is_authenticated() и FooBar::Auth->username().
 is_authenticated() берет две куки, предоставленные браузером, login и
 password.  Если хотя бы одной куки нет, то возвращается false.  Потом
 из куки login берется имя пользователя и в таблице юзеров ищется
 соответствующий ему пароль.  Если пароль не найден, возвращается
 false.  Hайденный пароль хэшируется с помощью md5 и сравнивается с
 содержимым куки password().  Если эти значения определены и равны, то
 возвращается true.  В противном случае возвращается false.
 
 Итак, is_authenticated() отвечает на вопрос: "можно ли доверять имени
 пользователя, приехавшему в куке login?".  Только если ответ -- "да",
 то можно использовать метод ->username().  У меня в этом методе даже
 делается внутренняя проверка:
 
          # несмотря на то, что сам метод вызывается из-под проверки на
    # is_authenticated()
    if (!$self->is_authenticated()) {
             croak "Internal error: user is not authenticated";
          }
 Собственно, последняя задача FooBar::Auth -- это функция "logout".
 FooBar::Logout вызывает метод FooBar::Auth->drop_credentials().  Этот
 метод генерирует две пустые куки "login" и "password", а
 FooBar::Logout отдает их браузеру, чтобы закрыть сессию.
 Отдельно есть модуль, который занимается авторизацией, например,
 позволяет юзеру "petya" и "vasya" добавлять новости на сайт, а юзеру
 "vasya" -- ещё вдобавок модерировать форум.
 Авторизацией занимается модуль FooBar::Authz.  При создании этого
 модуля ему передается экземпляр текущего модуля FooBar::Auth.
 
 У FooBar::Authz есть метод ->has_permission($username, $permission).
 
 Первое, что делает этот метод -- вызывает $auth->is_authenticated(), и
 если нет -- то возвращает false.  
 
 Если да, пользователь валидный, то вызывается $auth->username(), и
 лезется в отдельную таблицу прав доступа, чтобы проверить, есть ли у
 такого пользователя право "add-news" или "moderate-forum".
 
 Как-то так.  О том, как правильно управлять аутентификатором и
 авторизатором, вы узнаете в следующей серии.
 
 --alexm
 --- ifmail v.2.15dev5
  * Origin: tyranny (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 <без заголовка>   Nick Knutov   20 May 2003 20:56:02 
 Re: (no subject)   Andrew Alakozow   21 May 2003 12:13:50 
 (no subject)   Nick Knutov   20 May 2003 22:03:38 
 (no subject)   Nick Knutov   20 May 2003 22:06:32 
 Re: <none>   Alexey Mahotkin   24 May 2003 18:42:29 
 О праведном accounting\'е (was: <none>)   Dennis Krupenik   26 May 2003 15:35:46 
 Re: О праведном accounting\'е (was: <none>)   Artem Chuprina   26 May 2003 15:51:07 
 Re: О праведном accounting\'е (was: <none>)   Alexey Mahotkin   26 May 2003 22:22:47 
Архивное /ru.perl/386596cebca4.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional