Лучшие практики для SPA с входом в систему oauth - Vue NodeJS MySQL - PullRequest
0 голосов
/ 09 октября 2019

У меня есть приложение Vue, и я использую nodejs и MySQL в качестве моего бэкэнда. Я хочу выполнить вход с помощью Google, Facebook и локального входа.

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

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

Кто-нибудь знает, как я это делаю ~ 100% безопасно с проверенным запросом к бэкэнду и максимально просто?

Спасибо

1 Ответ

0 голосов
/ 09 октября 2019

Отказ от ответственности: я реализовал oauth-потоки только для корпоративных систем, которые, казалось, всегда каким-то образом игнорировали потоки в библиотеках и, таким образом, используются для реализации потоков вручную. Этот пост предназначен для того, чтобы дать вам некоторые пояснения о том, как работает oauth, о различных потоках, которые происходят, и о том, какая информация вам нужна в каком месте.

Насколько мне известно, есть три потока Oauth, которыеЗаурядное веб-приложение обычно использует, а именно:

  • Потоки, которые используют Код авторизации , который обменивается на Маркер доступа
  • Потоки, которые напрямую возвращают токен доступа .
  • Потоки, которые требуют от пользователя ввода своего имени пользователя и пароля на вашем сайте, который затем обменивается на Accessтокен в вашем бэкэнде

Есть еще несколько потоков oauth, но они здесь не актуальны. Вы можете прочитать о них на веб-сайте oauth.net .

Для приложений с собственным лицевым и внутренним интерфейсом, код авторизации является подходящим вариантом. Для приложений с только внешним интерфейсом и без API-интерфейса, которым вы управляете, полезен поток с использованием только токена доступа. Третий вариант рискован, потому что (например) вы просите людей ввести свои учетные данные Google на example.com. Вы могли бы сдержать свое слово и только завершить поток oauth этим ... или вы не могли и выдать себя за пользователя. Первые два потока отделяют процесс входа в систему от сайта, для которого вы аутентифицируетесь, только разделяя доступ через токен.

Получение вашего бэкэнда для доверия токену

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

  • Ваше приложение открывает страницу от поставщика Oauth , определяя URL перенаправления . Иногда вы определяете два, один для успеха и один для отказа.
  • Пользователь вводит свои учетные данные на странице Oauth-провайдера
  • Oauth-провайдера генерирует токен авторизации и перенаправляет на URL-адрес перенаправления с токеном авторизации

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

Аутентификацияконкретный пользователь

Как правило, вы хотите, чтобы в вашем API-интерфейсе было понятие «пользователь», полностью отделенное от Oauth, поскольку вам не нужно каждый раз запрашивать информацию у поставщика Oauth, когда вам требуется какая-то информация. о пользователе, и потому что это делает вашу жизнь намного проще при внедрении нового поставщика Oauth или вашей собственной схемы имени пользователя / пароля. Это означает, что в отношении вашего приложения Vue ваш пользователь аутентифицируется только в том случае, если ваш API говорит, что это так. Он знает, что пользователь проходит проверку подлинности, когда у него есть какой-либо токен или файл cookie Bearer, который позволяет ему делать запросы API. Ваше приложение Vue не заботится о том, как этот токен или cookie Bearer появился.

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

  • Обменять токен авторизации на токен доступа у поставщика Oauth. Вы делаете это, отправляя http-запрос от вашего сервера напрямую к провайдеру oauth. Поставщик oauth ответит токеном доступа. Вы можете использовать этот токен доступа для получения информации о пользователе.
  • Выполните вызов с токеном доступа провайдеру Oauth, чтобы получить любую информацию, необходимую для поиска нужного пользователя в вашей базе данных.
  • Если вы нашли пользователя, теперь вы можете создать токен на предъявителя или сеанс дляэтот пользователь. Если вы не нашли пользователя, вы можете создать его, предложить пользователю создать его или выдать ошибку.
  • Вернуть маркер носителя или cookie сеанса во внешний интерфейс. Если вы сделали вызов API для передачи токена авторизации, он вам не нужен. Если вы ввели URL-адрес API в качестве URL-адреса перенаправления, вам придется каким-то образом передавать эту информацию. Вероятно, самый простой способ - это перенаправить на определенную страницу в вашем приложении, которая берет токен и сохраняет его где-то.

Как заставить его работать с помощью всплывающего окна

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

...