Аутентификация с помощью Passport + Facebook + Express + create-react-app + React-Router + proxy

TL;DR: Как мне инициировать процесс аутентификации Facebook со страницы в приложении React?

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

Мое приложение состоит из front-end-приложения-приложения-приложения, использующего маршрутизатор-ответ для маршрутизации. У меня это работает на порту 51000 в моей среде разработки. В package.json я использую "прокси" для перенаправления других маршрутов на мой экспресс-сервер, работающий на порту 51001. Это работает в целом для запросов в моих компонентах React, которые попадают на сервер. Например:

axios.get('/api/some-stuff')

При вызове в моем компоненте React это успешно ударит мой сервер Express.

Я хочу, чтобы мои внутренние маршруты были аутентифицированы, и я решил использовать Facebook auth через паспорт-facebook. Я установил это так же, как и многие онлайн-обучающие программы, которые я видел. Например, у меня есть маршрут на моем экспресс-сервере с именем '/auth/facebook'. Если я перейду на localhost: 51001/auth/facebook, он перенаправляет меня на facebook для входа в систему, а затем перенаправляет меня обратно на какой-то маршрут, который я ему дал. Таким образом, поток работает так, как ожидалось.

Конкретная проблема, с которой я столкнулась, - это заставить React успешно инициировать и завершить вызов api, запускающий auth. Я пробовал два подхода.

Подход 1: вызов маршрута через ajax

В своем компоненте componentDidMount я назвал следующее:

axios.get('/auth/facebook')

Это успешно удаляет мой экспресс-сервер, но затем немедленно генерирует следующую ошибку в консоли браузера:

XMLHttpRequest не может загрузить https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http%... 2Flocalhost% 3A51000% 2Fauth% 2Ffacebook% 2Fcallback & client_id = XYZ. Перенаправление из " https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http%... 2Flocalhost% 3A51000% 2Fauth% 2Ffacebook% 2Fcallback & client_id = XYZ в https://www.facebook.com/login.php? skip_api_login = 1 & api_key = XYZ... _ & display = page & locale = en_US & logger_id = 7f30b5a1-2ad1-dc31-f08b-70d3cfdd55fa 'заблокирован политикой CORS: заголовок "Access-Control-Allow-Origin" присутствует на запрошенном ресурсе. Происхождение ' http://localhost: 51000 ', следовательно, не допускается.

** Подход 2: Переход к маршруту в браузере **

Другое, что я пробовал, что я видел во всех учебниках, - это добавить ссылку на одну из моих страниц, которая просто переходит на маршрут аутентификации. Например:

<a href="/auth/facebook">Login with Facebook</a>

Однако, когда я нажимаю на это, я просто заканчиваю на http://localhost: 51000/auth/facebook или просто пустую страницу в моем приложении React. Прокси-сервер, который у меня есть, не срабатывает, и я не вижу никаких действий на моем Экспресс-сервере, когда я иду на этот маршрут в браузере, хотя это не Маршрут, который я определил в ответ-маршрутизаторе.

Поэтому я немного застрял здесь. Должен ли щелчок на этом теге инициировать запуск этого маршрута против моего экспресс-сервера? Есть ли способ сказать реактивному маршрутизатору игнорировать определенные маршруты, чтобы они перенаправлялись на мой экспресс-сервер? Это работает нормально при выполнении вызовов AJAX, но если я перейду на localhost: 51000/not/a/route, это не приведет к перенаправлению запроса на Express. Он просто загружает страницу реакции без содержимого.

Любая помощь приветствуется.

Спасибо,

-Dan

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

Поэтому я вроде как сейчас работаю, хотя я вовсе не уверен, что это "правильный" способ сделать что-то.

В моем приложении для реагирования (напомним, что он работает на порту 51000), у меня есть следующая ссылка:

<a href="#" onclick="location.href='http://localhost:51001/auth/facebook'; return false;">Facebook Login</a>

Обратите внимание, что это указывает прямо на мой сервер API, а не на ответный маршрут. Навигация по этой ссылке попадает на экспресс-сервер и сразу же перенаправляется на Facebook. Вход в систему перенаправляется обратно на мой экспресс-обратный вызов facebook, который сам перенаправляет на http://localhost: 51000/somePage, который теперь возвращается в мое приложение-ответ.

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

EDIT 2

Я открыт для того, чтобы кто-то говорил мне об этом, но я думаю, что мой нынешний подход на самом деле очень хорош. Я подумал, как все будет вести себя на производстве. Я отвечу на сайт www.example.com, с моим экспресс-сервером, доступным через api.example.com. Моя ссылка на вход в Facebook будет на "api.example.com/auth/facebook". Обратный вызов, предполагающий успешный аут, будет перенаправлен на "www.example.com/some/route". Я думаю, что разумно подпрыгнуть к URL-адресу "api", чтобы выполнить вход в систему. В конечном счете, нет смысла пытаться заставить реактор-маршрутизатор игнорировать определенные маршруты, так как все мои вызовы api будут направлены на явный маршрут.

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

** РЕДАКТИРОВАТЬ 3 **

Вот ссылки на мой проект. Не будет тривиально, чтобы весь проект работал, но есть только несколько файлов, связанных с потоком auth.

Вы можете просмотреть репо здесь: https://github.com/dan-goyette/Portfolio

Маршрутизатор Express для этого здесь:

https://github.com/dan-goyette/Portfolio/blob/master/portfolio-server/src/Routing/auth.js

В пользовательском интерфейсе я запускаю вызовы на экспресс-сервер, используя этот компонент:

https://github.com/dan-goyette/Portfolio/blob/75ca9326e6227d0601cdfa4c0cece672bd347302/portfolio-ui/src/Components/SocialMenuButton/SocialMenuButton.js

Вы можете увидеть, как он работает на странице https://www.dan-goyette.com/home, в верхней правой части.

Ответы

Ответ 1

Я также столкнулся с этой проблемой - изменение конфигурации прокси-сервера CRA показало, что это трюк:

"proxy": {
   "/api": {
      "target": "http://localhost:3001/"
   }
}

Если ссылка OAuth находится в /api/auth/foo, приложение CRA находится на localhost:3000, а экспресс-приложение - на localhost:3001

Ответ 2

Сегодня я столкнулся с одной и той же проблемой и решил ее, не используя прокси create-react-app сервер create-react-app, но вместо этого создав прокси-сервер в моем приложении для create-react-app.

В конце моего экспресс-приложения у меня есть

 // all routes above

 if (env.isDevelopment()) {
   const proxy = require('express-http-proxy')
   app.use('/*', proxy('http://localhost:3000'))
 } else {
   // probably serve up build version in production
 }

Просто не забудьте выключить прокси-сервер в пакете json вашего клиента, иначе вы можете получить бесконечный прокси-цикл или что-то еще.

Ответ 3

EDIT: Мой предыдущий ответ не имел никакого отношения к проблеме и не решал ее. Все в моем случае было вызвано registerServiceWorker в CLI, сгенерированном index.js. Просто удалите его, и все работает так, как должно.

//Remove this lines from index.js
import registerServiceWorker from './registerServiceWorker'

registerServiceWorker();

Ответ 4

Вы можете добавить свой локальный сервер для создания реакции на веб-приложение api. Перейдя на console.developers.google.com и добавьте локальное приложение create-react-app в "Авторизованные исходники JavaScript" и "Авторизованные URI-адреса перенаправления".

Ответ 5

Я исправил эту проблему, используя поле "Valid UAuth redirect URIs" в настройках Facebook Developer для разделов продуктов Facebook Login, например http://your-domain.loc:5000/auth/facebook.

И кнопка Facebook Auth должна быть:

<a href="#" onclick="location.href='http://your-domain.loc:5000/auth/facebook'; return false;">Login with Facebook</a>

Вы должны поместить туда свой URL-адрес перенаправления facebook. Еще одна вещь из моего примера: я использую 3000 портов для локального сервера узлов и 5000 для запроса API в своем приложении.

Я использую /etc/hosts для использования моего домена, а не localhost.

127.0.0.1   your-domain.loc

Работает для меня.

Кроме того, продолжается обсуждение ресурса GitHub с вопросом - https://github.com/facebook/create-react-app/issues/3502