paint-brush
НО, НО, НО AUTH — ЭТО ХА ...к@dbozhinovski
511 чтения
511 чтения

НО, НО, НО AUTH — ЭТО ХА ...

к Darko Bozhinovski8m2024/08/19
Read on Terminal Reader

Слишком долго; Читать

Нет, это не так. Это скучно, бюрократично, это решенная проблема... но не называйте ее сложной как общее утверждение.
featured image - НО, НО, НО AUTH — ЭТО ХА ...
Darko Bozhinovski HackerNoon profile picture


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


Мне "я использовал MD5 для хеширования паролей в PHP" лет. Конечно, это была ужасная идея, даже в 2012 году . Но тогда я не помню, чтобы считал аутентификацию "сложной". Это было довольно простое испытание само по себе - получить адрес электронной почты или имя пользователя, получить пароль, хешировать его (с MD5, как "бог задумал"), и если вы особенно заботитесь о безопасности, [ солить ] пароль. Сохраните все это где-нибудь, обычно в базе данных. Та-дам, регистрация завершена.


В наши дни повествование изменилось. «Аутентификация — это сложно» кажется вездесущим повествованием, которое находится в одном клике от HackerNews или Reddit. Но так ли это на самом деле? ИМХО, правда в том, что аутентификацию несложно создать — любой может ее изучить (и каждый в этой сфере деятельности должен изучить основы). Настоящая проблема заключается в дополнительных возможностях: MFA, управление пользователями, сброс паролей, каждый из сотен поставщиков OAuth и объединение учетных записей от разных поставщиков. Это смерть от тысячи порезов. Поскольку аутентификация — это решенная проблема, изобретение велосипеда — не лучшее использование вашего времени. Но это не значит, что «аутентификация — это сложно» как общее утверждение верно или даже близко к верному. Вы должны экспериментировать, понимать основы и строить на этом. Сложность только растет с масштабом (или потенциальным масштабом) того, что вы создаете.


Итак, насколько сложной может быть аутентификация? Давайте разберемся.


В былые времена...

Продолжая рассказ о PHP и md5, создание функциональности входа в систему следовало схожему набору шагов: получить адрес электронной почты и пароль, проверить наличие адреса электронной почты в вашем хранилище, хешировать пароль вместе с солью, сохраненной для этого адреса электронной почты, сравнить полученный хеш с тем, который хранится в базе данных, и, если все работает нормально, установить cookie-файл с помощью setcookie (мы все еще находимся в стране PHP — не то чтобы общая логика сильно отличалась в других экосистемах).


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


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


Скрути свой собственный - "современный" подход

Электронная почта/пароль и соц. аутентификация

Чтобы добраться до того, где мы сейчас находимся, начнем с самого начала... Удивительно, я знаю. Мы, вероятно, согласимся, что этих компонентов достаточно для PoC email/пароля + входа через социальную сеть:


  1. Сервер, который обрабатывает маршруты — регистрация, вход, выход...
  2. Некое хранилище для хранения записей пользователей (массив в памяти тоже подойдет)
  3. Виды — экраны входа в систему, регистрации и аутентификации «панели управления».
  4. Обработчики для социальной аутентификации


Если взять Express и Passport, то, поскольку мы не собираемся изобретать велосипед, мы получим ровно 150 строк очень, очень скучного и повторяющегося кода: https://github.com/supertokens/auth-express/blob/master/index.mjs . Следующий раздел будет поверхностным объяснением того, что происходит в коде, так что можете смело пропустить его , если вы уже знакомы с концепциями. Приложение Express в любом случае является PoC.


Давайте быстро разберем это:

Рендеринг вещей на экране

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


Поскольку это PoC, мы не будем использовать все эти React-навороты. Обычный SSR с ejs тоже подойдет: https://github.com/supertokens/auth-express/tree/master/views

Добавление маршрутов

Основываясь на некоторых примерах passport.js , но еще более упрощенных, нам понадобится следующее:

  1. Некоторые deps: npm i passport passport-local express-session . Давайте кратко рассмотрим каждый:

    1. Passport.js — промежуточное ПО аутентификации OG для Express и Node.
    2. passport-local — стратегия аутентификации для Passport; Стратегия аутентификации в модуле, который обрабатывает процесс аутентификации для определенного метода аутентификации — в данном случае локальный вход с использованием имени пользователя (адреса электронной почты) и пароля.
    3. express-session — промежуточное ПО, которое управляет данными сеанса, позволяя вам хранить и сохранять сеансы пользователя между HTTP-запросами. Оно работает, назначая уникальный идентификатор сеанса каждому клиенту, который хранится в cookie на стороне клиента и используется для извлечения данных сеанса на сервере.
  2. Место для хранения наших пользователей (пример, ссылка на который приведена выше, использует массив в памяти): https://github.com/supertokens/auth-express/blob/master/index.mjs#L13

  3. Конфигурация для нашего экземпляра паспорта и нашего экземпляра LocalStrategy для обработки входящих запросов на поиск пользователей: https://github.com/supertokens/auth-express/blob/master/index.mjs#L18

  4. Инициализируйте паспорт ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L60 ) и экспресс-сессию ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L69 ).


Многословно, конечно. Сложно? Я так не думаю, по крайней мере, не в смысле «внедрить как игрушку». Но мы уже давно отошли от использования комбинаций email/пароль. Давайте проверим, насколько сложно добавить социальный провайдер поверх того, что у нас есть.


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


Если вы решите следовать всем инструкциям, вот ссылка, описывающая, как получить эти ключи GitHub: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app О, и кстати, те, что в репозитории, недействительны, на случай, если вы волновались ;)

Интеграция GitHub OAuth2 в наш PoC

Прежде всего, нам нужна еще одна зависимость, npm i passport-github2 . passport-github2 — это стратегия аутентификации для Passport, позволяющая нам интегрироваться с API OAuth2 GitHub.


Некоторые обработчики ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L122-L133 ) и конфигурация ( https://github.com/supertokens/auth-express/blob/master/index.mjs#L29-L45 ) позже, ну, вот и все. Сложно? Вероятно, нет. Бюрократизм? Еще бы. Скучно? Безусловно. Особенно, если вам приходится делать это снова и снова. Это решенная проблема; изобретение велосипеда часто не является лучшим использованием времени, как мы установили.


Большая идея

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


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


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

  • 2FA, МИД
  • Сброс пароля
  • Каждый из сотен поставщиков OAuth со своей спецификой
  • Управление пользователями
  • Объединение счетов от разных провайдеров
  • Охватить все возможные крайние случаи и потенциальные бреши в безопасности
  • ...и я могу продолжать


Мы, вероятно, можем реализовать каждый из них. И сам по себе каждый элемент может считаться простым. Но он складывается. Так что это не обязательно реализация — это ее поддержание, ответственность за нее, соответствие стандартам, нарушения безопасности и так далее. Плюс, поднимите руки — кто из вас любит читать RfC? Я не думаю, что я увидел бы много поднятых рук, если бы мы были на встрече.


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


Поэтому естественным вопросом будет: когда следует сворачивать свой собственный?

Проекты игрушек, инди-игры и образовательные проекты

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

Стартапы

В общем, если вы создаете продукты, не создавайте собственную аутентификацию. Это переизобретение очень скучного и бюрократического колеса. У вас есть множество вариантов выбора. Плюс, вы что-то создаете, верно? Зачем мы вообще ведем этот разговор, если ваш продукт не аутентифицирован?

Масштабирование и выше (как бы мы ни определяли их)

Не надо. Та же причина, что и в случае со стартапами, но здесь это, безусловно, применимо больше.


Вы, вероятно, понимаете, к чему я клоню. «Auth is hard» — это, я бы сказал, маркетинговый ход, когда используется как общее заявление. Вы можете понять auth, вы можете его создать, но он скучный, его неинтересно поддерживать, и это проблема, которая решается. Таким образом, его можно считать товаром — тем, который вы можете взять с полки в любом виде, который вы выберете (некоторые варианты ниже).

Ландшафт самообслуживания и FOSS

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

Библиотеки аутентификации

  • Passport.js, подробно описанный выше
  • Lucia — простая и гибкая библиотека аутентификации для современных веб-приложений, ориентированная на удобство разработки и простоту использования.
  • Auth.js — легкая и настраиваемая библиотека аутентификации для Node.js, разработанная для легкой интеграции в различные фреймворки и приложения. Начиналась как библиотека для Next.

Серверы аутентификации

  • Keycloak — сервер управления идентификацией и доступом с открытым исходным кодом, предлагающий такие функции, как единый вход (SSO), посредничество в идентификации и федерацию пользователей.
  • SuperTokens (см. отказ от ответственности выше) — решение для аутентификации с открытым исходным кодом, предоставляющее встроенные функции, такие как управление сеансами, вход через социальные сети и аутентификация по электронной почте/паролю, с упором на безопасность и простоту.
  • FusionAuth — гибкая платформа аутентификации для разработчиков, предлагающая такие функции, как управление пользователями, многофакторная аутентификация (MFA) и единый вход (SSO).
  • Authelia — сервер аутентификации с открытым исходным кодом, обеспечивающий многофакторную аутентификацию (MFA) и единый вход, предназначенный для защиты приложений с использованием обратных прокси-серверов.

Хранилище + Аутентификация

  • Supabase — платформа с открытым исходным кодом, работающая по принципу «бэкэнд как услуга» (BaaS), предоставляющая возможности базы данных, аутентификации и работы в реальном времени, разработанная как альтернатива Firebase.
  • Pocketbase — серверное решение с открытым исходным кодом, объединяющее базу данных, аутентификацию и хранилище файлов, призванное упростить разработку современных веб- и мобильных приложений.


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

Вывод: аутентификация — это «бюрократия» разработки

Мой «большой» вывод — избегать изобретения велосипедов, особенно если это решенная проблема, как auth. Узнайте больше о колесах, поэкспериментируйте с ними, соберите игрушечное колесо и поймите его. Но, пожалуйста, пожалуйста, не продавайте его как нечто невыносимо сложное для понимания и сборки. Обучайте, а не привратничайте.