Какова правильная / стандартная практика аутентификации пользователя после регистрации? - PullRequest
0 голосов
/ 18 мая 2019

Я пытаюсь аутентифицировать пользователя после регистрации.Какой правильный или стандартный способ сделать это?

Используя этот метод в качестве способа его реализации, на шаге 3, как я могу сгенерировать случайный хеш для отправки пользователям по электронной почте?Я вижу два разных варианта:

  1. crypto
  2. токен JWT

В настоящее время я использую JWT для входа в систему, поэтому имеет ли смысл использоватьтот же токен для подтверждения пользователя?Почему или почему нет, а если нет, то как правильно?

1 Ответ

1 голос
/ 18 мая 2019

Ответ на ваш вопрос о том, следует ли использовать криптографический хеш или токен, - ни тот, ни другой.

Хэш, который вы генерируете для использования в качестве метода проверки, не обязательно должен быть криптографически безопасным, он должен быть только уникальным проверочным хэшем, который нелегко угадать.
В прошлом я использовал UUID v4 с UUID lib, и он работает просто отлично. Вы также можете создать 64 известную часть информации о пользователе, например, его идентификатор или адрес электронной почты, соединенные с чем-то случайным, например время в микросекундах и случайную шестнадцатеричную строку существенной длины, но, честно говоря, время, необходимое для создания чего-то подобного, впустую, когда UUID v4 работает просто отлично.

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

[РЕДАКТИРОВАТЬ]

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

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

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

ПЛОХО

/verify/<verification hash>
или
/verify?hash=<verification hash>

Имея только проверочный хеш в URL, вы полагаетесь на то, что это значение будет глобально уникальным в вашем хранилище данных. Если вы можете надежно генерировать уникальные значения, которые никогда не содержат коллизий, тогда все будет в порядке, но зачем вам об этом беспокоиться? Не полагайтесь на проверочный хеш отдельно.

ХОРОШО

/users/<id>/verify/<verification hash>
или
/users/<id>?action=verify&hash=<verification hash>

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

Указанные выше схемы URL действительно работают только в том случае, если ваши идентификаторы пользователя безопасны для публичного показа. Как правило, вы никогда не должны использовать свои идентификаторы хранилища данных в URL, особенно если они являются последовательными INT. Существует множество опций для идентификаторов, которые вы использовали бы в URL-адресе, например UUID v1 или HashIDs или любая реализация короткого идентификатора.

ТАКЖЕ

Хороший способ увидеть, как это делается в естественных условиях, - это просмотреть электронные письма, которые вы получили от других систем, с просьбой подтвердить свой адрес электронной почты. Многие могут использовать формат:
/account/verify/<very long hash>

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

ПРИМЕЧАНИЕ. Хотя этот метод может быть наиболее «безопасным», я упоминаю об этом только потому, что он основан на типичных методах, используемых сторонними библиотеками, которые не делают предположений относительно вашей модели пользовательских данных. Вы можете реализовать этот стиль, если хотите, но это будет больше работы. Мой ответ сфокусирован на вашем намерении выполнить базовую проверку на основе данных вашей пользовательской модели.

БОНУС

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

...