Авторизовать пользователя в форме. Блог GetCourse

Почему oauth, а не виджет «войти через»?

Нет проблем. Если вас устраивают функционал, дизайн и уровень безопасности виджета — то его воткнуть в код на самом деле намного проще — можете дальше не читать.

Почему oauth, а не openid?

Потому что OpenID практически бесполезен для тех целей, для которых декларирован. Это сугубо мое мнение, но оно опирается не на пустое место.

Во-первых, OpenID пользуются в основном «гики», процент которых в интернете не настолько высок, чтобы перестраивать под них сайты (за некоторым исключением, разумеется 🙂 ) Почему так? Потому что для того, чтобы получить OpenID аккаунт, надо — его получить.

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

image

. Ну какой казуальный пользователь будет это делать? А с OAuth все намного проще — видит человек кнопку «Войти через ВКонтакте», нажимает, и… уже на сайте с правами зарегистрированного пользователя. «Будьте проще», — говорил классик, — «и люди к вам потянутся». Как в воду глядел.

Во-вторых, возможности OAuth далеко не исчерпываются аутентификацией и авторизацией. Получив в процессе авторизации токен, его можно использовать для дальнейшей интеграции возможностей социалки в свой ресурс — чтение/написание постов, доступ к френдленте и стене и многое другое.

В-третьих, OpenID активно пользуются спамеры и хакеры. Зачастую реализация OpenID аутентификации на ресурсе делается без особого внимания к известным его уязвимостям — по одному только описанию протокола на OpenID-провайдере или с помощью неизвестно кем и когда написанной библиотеки.

Похожее:  Безопасная аутентификация и авторизация | Аутентификация |

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

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

Кроме того, OpenID аутентификация, в сущности, не дает никаких гарантий клиенту. Она подтверждает лишь, что запрашиваемый пользователь действительно зарегистрирован на одном из OpenID-серверов — и все. Механизмы получения дополнительной информации о пользователе (email, имя, возраст) имеются, но мало кем поддерживаются.

Можно, конечно, в нарушение идей OpenID, анализировать идентификатор и доверять только определенным OpenID-провайдерам (например, тем же социалкам). Но смысл, если почти все из них (за исключением ЖЖ, но он и по OpenID ровным счетом ничего не расскажет о пользователе)

Google

1. Идем

. Создаем новый проект. На вкладке API access нажимаем кнопку «Create an OAuth2 client ID».

image

Получаем client_id(Client ID) и secret_key(Client Secret).

image

2. Код кнопки должен быть вида:

Авторизовать пользователя в форме

2. «Полная авторизация, без пароля» — при таком варианте вводить пароль после заполнения формы пользователю не потребуется, что позволит сразу авторизовать его в аккаунте и дать ему полный доступ к данным профиля, а также к купленным тренингам.

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

Обратите внимание, настройка «Полной авторизации без пароля» находится в категории «Еще варианты». Однако, если эта настройка уже выбрана, она будет отображаться сразу.

Битые ссылки в решениях верховного суда

Неправильно. Теперь я четко вижу, что мы не согласны друг с другом. Вы и я.

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

— Тим Бернерс-Ли, 1993

Половины URL-адресов, на которые ссылается Верховный Суд США, уже не существует. Если вы читаете академическую работу в 2022 году, и написана она была в 2001 году, то с большой вероятностью любой URL там будет нерабочим.

В 1993 году многие страстно верили, что URL отомрет, и на замену ему придет URN. Uniform Resource Name — это постоянная ссылка на любой фрагмент, который, в отличие от URL, никогда не изменится и не сломается. Тим Бернерс-Ли описал его как «срочную необходимость» еще в 1991.

Простейший способ создать URN — это использовать криптографический хэш содержания страницы, например:urn:791f0de3cfffc6ec7a0aacda2b147839. Однако, этот метод не удовлетворяет критериям веб-сообщества, так как невозможно выяснить, кто и как будет конвертировать этот хэш обратно в реальный контент.

В 1996 Киф Шэйфер и несколько других специалистов предложили решение проблемы поломанных URL. Ссылка на это решение сейчас не работает. Рой Филдинг опубликовал предложение реализации в июле 1995 года. Ссылка тоже поломана.

Я смог найти эти страницы через Google, который по сути сделал заголовки страниц современным аналогом URN. Формат URN был окончательно оформлен в 1997 году, и практически не использовался с тех пор. У него интересная реализация. Каждый URN состоит из двух частей: authority, который может преобразовать определенный тип URN, и конкретный идентификатор документа в понятном для authority формате.

Учитывая мощность поисковых движков, возможно, что лучшим на сегодня форматом URN могла бы стать простая возможность файлов ссылаться на свой прошлый URL. Мы можем позволить поисковым движкам индексировать эту информацию, и ссылаться на наши страницы корректно:

Веб-приложение

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

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

Вконтакте

1. Идем

. Тип — «Веб-сайт». Вводим базовый домен и адрес сайта. На странице настроек получаем client_id (ID приложения) и secret_key (защищенный ключ).

image

2. Втыкаем в код кнопку вида

Всё хорошо?

Почти. Данная система по-прежнему не защищает от кражи хэша из кук при открытом канале и отсутствии SSL. Кроме того, сложно обеспечить своевременную блокировку, если доступ к аккаунту утерян (особенно если взломщик уже сменил пароль). В этом случае очень помог бы сброс пароля через смс-команду с привязанного телефона — но для этого уже нужна возможность принимать и отправлять смс.

А если она есть — то можно сразу внедрить двухфакторную авторизацию, которая снимет массу проблем. Но не проблему с необходимостью в SSL — поскольку всё равно результатом любой авторизации является получение некого токена доступа, работающего ограниченное время. И этого времени может быть достаточно, чтобы сделать от нашего имени что-то, что нам не понравится.

Делегирование полномочий

Давайте попробуем создать отдельный модуль. Назовём его совершенно бесхитростно — security.php, и оформим как отдельный скрипт. Будем подключать его ко всем закрытым страницам нашего проекта в самом начале. Внутри этого файла будем анализировать некие условия, а по итогам его работы выставлять специальный флаг в 0 или 1. Пусть этот флаг будет храниться в переменных сессии (массив $_SESSION в PHP).

Что нам это даёт? Мы можем запихать в этот скрипт сколь угодно хитрую логику, вплоть до анализа последних действий пользователя и добавления его в бан-лист по IP, либо блокировки его аккаунта на тот или иной срок. Но сперва реализуем очень базовую функциональность: будем сверять значение хэша, пришедшего из куки, с тем, что должно было бы получиться, если хэш не был искажён. Сервер знает IP, знает юзер-агент, знает пароль текущего пользователя… Кажется, всё готово!

Как быть?

Очевидно, с этим надо что-то делать. Да, можно сразу бежать покупать сертификат и подключать SSL. Но можно сделать кое-что ещё до этого, и существенно снизить тем самым необходимость в нём. В конце концов, в том же ВКонтакте SSL стал принудительным всего полгода назад, а до этого как-то ведь жили.

Первое, что приходит на ум — хранить вместо пароля хэш от него. Это не особо поможет, если кто-то перехватит трафик, и не поможет при краже кук. Но вот в ситуации «кто-то открыл настройки и прошёлся по кукам, пытаясь запомнить значения» — сильно усложнит жизнь злоумышленнику.

Можно пойти дальше, и при создании хэша использовать юзер-агент. Теперь взломщику придётся использовать браузер той же версии, что и у нас (а в случае с IE ещё и с тем же набором плагинов тех же самых версий, что выходит уж очень маловероятно, особенно если взломщик не догадался подсмотреть юзер-агент).

Как это работает.

Если кому интересны все подробности, то см. ссылки выше. А вкратце — так:

Кротовые холмики и горы

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

— Тим Бернерс-Ли, 1993

Одноклассники

1. Регистрируемся как разработчик

. Идем

и заполняем заявку на получение OAuth доступа. Н-да. Заявка, похоже, обрабатывается вручную. Если ответа в течение суток нет, пинаем поддержку по тому же адресу. «Одноклассники», что тут скажешь…

2. Получаем письмо с инструкциями и, следуя им, заполняем форму.

image


Все заполненные в примере поля обязательны к заполнению. Нажимаем «Сохранить» и получаем письмо на указанный емайл, содержащее client_id(Application ID), public_key(Публичный ключ приложения) и secret_key(Секретный ключ приложения)

3. Код кнопки должен быть вида:

Параметры запроса

Формат application/x-www-form-urlencoded — это аномальный монстр во многих отношениях, результат многих лет случайностей реализаций и компромиссов, которые привели к необходимому для интероперабельности набору требований. Но это точно не образец хорошей архитектуры.

WhatWG URL Spec

Практические рекомендации по реализации

Разумеется, в первую очередь надо зарегистрироваться в соцсети, активировать аккаунт, ну и всё такое. Не торопиться. Некоторые сервера не сразу корректно обрабатывают запросы от свежезарегистрированных OAuth-клиентов. Здесь я расписал только успешные потоки, забывать про обработку ошибок — никак не стоит.

Также я практически не уделил внимания аспектам безопасности — это тема отдельной статьи. Как минимум, везде, где можно передавать уникальный параметр в callback-url для каждого пользователя — это стоит делать (Основной callback адрес должен оставаться без изменений, а меняться — только параметр, иначе сервер не пропустит запрос.

Предыстория

Осень 2022-ого. Примерно полтора года назад, когда мне случилось стать участником разработки проекта, где пользователей существенно больше пары десятков человек, я наконец-то впервые в своей жизни задумался о надёжности авторизации.

По сути, авторизация — это то, с чего начинается процесс взаимодействия зарегистрированного пользователя с системой (для незарегистрированного пользователя всё начинается с регистрации, и эти два процесса, как вы уже догадались, очень сильно взаимосвязаны). Я внезапно осознал, что во всех проектах, что я делал до этого, с безопасностью всё очень плохо.

Ссылка для входа и выхода

Функция “wp_loginout” выводит ссылку для “входа” для неавторизованных пользователей и “выхода” для авторизованных. У функции есть всего два аргумента:

Ссылка для регистрации, входа и выхода

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

Для получения адреса страницы с формой авторизации используйте функцию “wp_login_url”. Эта функция распечатает ссылку для входа. Если пользователь кликнет на неё, то он попадёт на форму авторизации “/wp-login.php” :

wp_login_url( $redirect, $force_reauth );

У функции есть два параметра:

НазваниеТипОписание
$redirectстрокаАдрес страницы, куда надо отправить пользователя после выхода. По умолчанию: “” (та же самая страница)
$force_reauthлогическийНужно ли сделать принудительную переавторизацию, даже если куки авторизации уже установлены). По умолчанию: false (не нужно)

Пример использования:

Стандартная реализация

Итак, сессия в PHP по умолчанию хранится в файле. Её id сохраняется в cookie (если куки отключены — задействуется механизм передачи через адресную строку, если это не отключено в конфигурации). Время жизни такой сессионной куки по умолчанию — до момента закрытия браузера (и обычно его никто не меняет).

Поэтому более продвинутые программисты реализуют галочку «запомнить меня», либо реализуют её функционал по умолчанию, без возможности отключить. Что они делают? Просто сохраняют в собственной куке айди пользователя. Но поскольку просто айди хранить как-то уж слишком стрёмно (любой может поставить любое число и получить доступ к произвольному аккаунту), то часто вместе с айди за компанию сохраняют и пароль. В открытом виде.

Если кто-то не понимает, чем это плохо — представьте себе, что у нас пользователь пользуется очень старым, либо очень плохо реализованным браузером. Мы ведь не можем гарантировать, что браузер надёжно шифрует куки? Да и вирусы всякие могут быть у пользователя на компьютере, и в случае особо серьёзной малвари может не спасти и шифровка — зловред может попытаться считать значения прямо из памяти, когда они расшифрованы.

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

Ну и самое главное — если у нас SSL используется только при авторизации (а на остальных страницах его решили отключить ради выигрыша в скорости, либо чтобы лучше работало промежуточное кэширование)… То наш пароль всё время передаётся открытым текстом.

Фрагменты

Часть URL после символа ‘#’ известна как «фрагмент» (fragment). Фрагменты были частью URL со времен первой спецификации, они использовались для создания ссылки на конкретное место на загруженной странице. Например, если у меня есть якорь на сайте:

Я могу сделать на него ссылку:

Яндекс

1. Идем

Вывод формы для авторизации/регистрации

Функция “wp_login_form” выводит форму для авторизации и регистрации. У функции есть только один аргумент, в который необходимо передавать массив с параметрами:

wp_login_form( $args );

Рассмотрим ключи и значения массива “$args”:

Приведём пример использования этой функции:

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

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