Я прошел через это с sled.com. Здесь возникает множество проблем, связанных с созданием учетных записей и поддержкой нескольких сторонних учетных записей для входа в систему. Некоторые из них:
- Нужно ли поддерживать как локальный пароль, так и сторонние логины?
Для sled.com я решил удалить локальный пароль из-за небольшого значения, которое он добавляет, и дополнительных затрат на защиту формы ввода пароля. Существует много известных атак для взлома паролей, и если вы собираетесь вводить пароли, вы должны убедиться, что их нелегко взломать. Вы также должны хранить их в одностороннем хеше или что-то подобное, чтобы предотвратить утечку.
- Насколько гибко вы хотите поддерживать несколько сторонних аккаунтов?
Похоже, вы уже выбрали трех провайдеров входа в систему: Facebook, Twitter и LinkedIn. Это здорово, потому что это означает, что вы используете OAuth и работаете с четко определенным набором доверенных поставщиков. Я не фанат OpenID. Остается вопрос, нужно ли вам поддерживать несколько сторонних учетных записей от одного поставщика (например, одну локальную учетную запись с двумя связанными учетными записями Twitter). Я предполагаю, что нет, но если вы это сделаете, вам нужно будет учесть это в вашей модели данных.
Для Sled мы поддерживаем вход через Facebook, Twitter и Yahoo! и в каждой учетной записи пользователя сохраните ключ для каждого из них: {"_id": "djdjd99dj", "yahoo": "dj39djdj", twitter: "3723828732", "facebook": "12837287"}. Мы устанавливаем кучу ограничений, чтобы гарантировать, что каждая сторонняя учетная запись может быть связана только с одной локальной учетной записью.
Если вы собираетесь разрешить несколько учетных записей от одного и того же стороннего поставщика, вам нужно будет использовать списки или другие структуры для поддержки этого, а вместе с этим и все другие ограничения для обеспечения уникальности.
- Как связать несколько аккаунтов?
Когда пользователь впервые регистрируется в вашей службе, он сначала обращается к стороннему поставщику и возвращается с проверенным сторонним идентификатором. Затем вы создаете для них локальную учетную запись и собираете любую другую информацию, которую хотите. Мы собираем их адрес электронной почты, а также просим их выбрать локальное имя пользователя (мы пытаемся предварительно заполнить форму их существующим именем пользователя от другого поставщика). Наличие некоторой формы локального идентификатора (адрес электронной почты, имя пользователя) очень важно для восстановления учетной записи позже.
Сервер знает, что это вход в систему впервые, если в браузере нет файла cookie сеанса (действительного или просроченного) для существующей учетной записи, а используемая сторонняя учетная запись не найдена. Мы пытаемся сообщить пользователю, что он не просто входит в систему, но и создает новую учетную запись, чтобы, если у него уже была учетная запись, вместо этого он, скорее всего, приостановился и вошел в систему со своей существующей учетной записью.
Мы используем точно такой же поток для связывания дополнительных учетных записей, но когда пользователь возвращается от третьей стороны, наличие действительного файла cookie сеанса используется, чтобы отличить попытку связать новую учетную запись с действием входа в систему. Мы разрешаем только одну стороннюю учетную запись каждого типа и, если она уже существует, блокируем действие. Это не должно быть проблемой, потому что интерфейс для связи с новой учетной записью отключен, если у вас уже есть одна (на одного провайдера), но на всякий случай.
Если пользователь пытался связать новую стороннюю учетную запись, которая уже связана с локальной учетной записью, вы просто предлагаете ему подтвердить, что он хочет объединить две учетные записи (при условии, что вы можете обработать такое слияние с вашим набором данных - часто легче сказать чем сделано). Вы также можете предоставить им специальную кнопку для запроса слияния, но на практике все, что они делают, - это связывают другую учетную запись.
Это довольно простой конечный автомат. Пользователь возвращается со сторонней стороны с идентификатором сторонней учетной записи. Ваша база данных может находиться в одном из трех состояний:
- Учетная запись связана с локальной учетной записью, и нет файла cookie сеанса -> Вход
- Учетная запись связана с локальной учетной записью, и файл cookie сеанса присутствует -> Объединить
- Учетная запись не связана с локальной учетной записью, и нет файла cookie сеанса -> Регистрация
Учетная запись не связана с локальной учетной записью, и файл cookie сеанса присутствует -> Связывание дополнительной учетной записи
- Как выполнить восстановление аккаунта у сторонних провайдеров?
Это все еще экспериментальная территория. Я не видел идеального UX для этого, так как большинство сервисов предоставляют как локальный пароль рядом со сторонними учетными записями, и поэтому фокусируются на сценарии использования «забыл мой пароль», а не на всем остальном, что может пойти не так.
С Sled мы решили использовать "Нужна помощь при входе?" и когда вы нажимаете, спросите пользователя его адрес электронной почты или имя пользователя. Мы ищем его и, если найдем подходящую учетную запись, отправим пользователю по электронной почте ссылку, по которой он может автоматически войти в службу (на один раз). Оказавшись здесь, мы перенаправляем их прямо на страницу привязки учетных записей, говорим им, что они должны взглянуть и потенциально связывать дополнительные учетные записи, и показываем им сторонние учетные записи, которые они уже связали.