Нет, это не так. Это скучно, бюрократично, это решенная проблема... но не называйте ее сложной как общее утверждение.
Мне "я использовал MD5 для хеширования паролей в PHP" лет. Конечно, это была ужасная идея, даже в 2012 году . Но тогда я не помню, чтобы считал аутентификацию "сложной". Это было довольно простое испытание само по себе - получить адрес электронной почты или имя пользователя, получить пароль, хешировать его (с MD5, как "бог задумал"), и если вы особенно заботитесь о безопасности, [ солить ] пароль. Сохраните все это где-нибудь, обычно в базе данных. Та-дам, регистрация завершена.
В наши дни повествование изменилось. «Аутентификация — это сложно» кажется вездесущим повествованием, которое находится в одном клике от HackerNews или Reddit. Но так ли это на самом деле? ИМХО, правда в том, что аутентификацию несложно создать — любой может ее изучить (и каждый в этой сфере деятельности должен изучить основы). Настоящая проблема заключается в дополнительных возможностях: MFA, управление пользователями, сброс паролей, каждый из сотен поставщиков OAuth и объединение учетных записей от разных поставщиков. Это смерть от тысячи порезов. Поскольку аутентификация — это решенная проблема, изобретение велосипеда — не лучшее использование вашего времени. Но это не значит, что «аутентификация — это сложно» как общее утверждение верно или даже близко к верному. Вы должны экспериментировать, понимать основы и строить на этом. Сложность только растет с масштабом (или потенциальным масштабом) того, что вы создаете.
Итак, насколько сложной может быть аутентификация? Давайте разберемся.
Продолжая рассказ о PHP и md5, создание функциональности входа в систему следовало схожему набору шагов: получить адрес электронной почты и пароль, проверить наличие адреса электронной почты в вашем хранилище, хешировать пароль вместе с солью, сохраненной для этого адреса электронной почты, сравнить полученный хеш с тем, который хранится в базе данных, и, если все работает нормально, установить cookie-файл с помощью setcookie
(мы все еще находимся в стране PHP — не то чтобы общая логика сильно отличалась в других экосистемах).
Выйти из системы было еще проще — просто аннулируйте куки на сервере, и все готово. Если сервер не видит куки при следующем запросе, вы не вошли в систему. Так что создание аутентифицированных маршрутов также было в целом простым испытанием. Все могло стать сложным, когда дело дошло до разрешений, но чаще всего, с приложениями, которые мне приходилось создавать, у нас были только администраторы и пользователи. Это было то, что вы могли просто хранить вместе с записью пользователя или в таблице разрешений, если вам когда-либо требовалось расширить количество ролей, которые у вас были для вашего приложения.
Полное раскрытие информации — я работаю в SuperTokens . Однако эта статья родилась из личного разочарования по поводу вездесущего повествования о том, насколько сложна аутентификация, как общего заявления. Другими словами, я не пытаюсь «продать вам свою вещь». Используйте то, что вам нравится.
Чтобы добраться до того, где мы сейчас находимся, начнем с самого начала... Удивительно, я знаю. Мы, вероятно, согласимся, что этих компонентов достаточно для PoC email/пароля + входа через социальную сеть:
Если взять 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 , но еще более упрощенных, нам понадобится следующее:
Некоторые deps: npm i passport passport-local express-session
. Давайте кратко рассмотрим каждый:
Место для хранения наших пользователей (пример, ссылка на который приведена выше, использует массив в памяти): https://github.com/supertokens/auth-express/blob/master/index.mjs#L13
Конфигурация для нашего экземпляра паспорта и нашего экземпляра LocalStrategy для обработки входящих запросов на поиск пользователей: https://github.com/supertokens/auth-express/blob/master/index.mjs#L18
Инициализируйте паспорт ( 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 О, и кстати, те, что в репозитории, недействительны, на случай, если вы волновались ;)
Прежде всего, нам нужна еще одна зависимость, 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.
Нет, на самом деле, я бы сказал, что как разработчик, нужно понимать основы того, как работает аутентификация. И я часто вижу повествование, которое утверждает обратное — что-то вроде «доверься мне, бро, мы можем справиться с этим за тебя». И конечно, я согласен, что по большей части, создание собственной аутентификации — пустая трата времени. Но это не так уж и сложно сделать, и это, конечно, не мистическая вещь. Где действительно становится сложно, так это со всем, что связано с аутентификацией и пользовательским опытом.
Подумайте об этом — в примере выше у нас есть работающая аутентификация. Вроде того. Но вот чего она не может делать (также упоминается в начале статьи):
Мы, вероятно, можем реализовать каждый из них. И сам по себе каждый элемент может считаться простым. Но он складывается. Так что это не обязательно реализация — это ее поддержание, ответственность за нее, соответствие стандартам, нарушения безопасности и так далее. Плюс, поднимите руки — кто из вас любит читать RfC? Я не думаю, что я увидел бы много поднятых рук, если бы мы были на встрече.
Я хочу сказать, что аутентификация непроста, если рассматривать ее в целом. Конечно, мы можем легко что-то сколотить для PoC, как мы сделали выше. Но это не магия, это не невозможно понять, и, пожалуйста, пожалуйста, не говорите так. Такая линия мышления (и маркетинга), по моему мнению, наносит ущерб всей отрасли.
Поэтому естественным вопросом будет: когда следует сворачивать свой собственный?
...конечно. Я бы даже поощрял это. Вы многому учитесь, делая, так почему бы и нет? Если ваш инди/игрушечный проект или блог вырастет и приобретет значительную базу пользователей или подписчиков, переключите его на сервис, решение с собственным хостингом или что-то еще. В конце концов, у вас есть продукт на тот момент, и ваше время, несомненно, будет лучше потрачено на создание этого продукта, а не на поддержание авторизации.
В общем, если вы создаете продукты, не создавайте собственную аутентификацию. Это переизобретение очень скучного и бюрократического колеса. У вас есть множество вариантов выбора. Плюс, вы что-то создаете, верно? Зачем мы вообще ведем этот разговор, если ваш продукт не аутентифицирован?
Не надо. Та же причина, что и в случае со стартапами, но здесь это, безусловно, применимо больше.
Вы, вероятно, понимаете, к чему я клоню. «Auth is hard» — это, я бы сказал, маркетинговый ход, когда используется как общее заявление. Вы можете понять auth, вы можете его создать, но он скучный, его неинтересно поддерживать, и это проблема, которая решается. Таким образом, его можно считать товаром — тем, который вы можете взять с полки в любом виде, который вы выберете (некоторые варианты ниже).
Для тех, кто хочет владеть своим стеком (как и вы), у вас также есть множество вариантов на выбор:
Библиотеки аутентификации
Серверы аутентификации
Хранилище + Аутентификация
Таким образом, даже если вы не хотите использовать стороннее программное обеспечение для аутентификации, вы можете просто выбрать готовое ПО с открытым исходным кодом в зависимости от ваших потребностей и предпочтений и использовать его.
Мой «большой» вывод — избегать изобретения велосипедов, особенно если это решенная проблема, как auth. Узнайте больше о колесах, поэкспериментируйте с ними, соберите игрушечное колесо и поймите его. Но, пожалуйста, пожалуйста, не продавайте его как нечто невыносимо сложное для понимания и сборки. Обучайте, а не привратничайте.