web-dev-qa-db-ja.com

Passport + Facebook + Express + create-react-app + React-Router +プロキシによる認証

TLDR:Facebookの認証プロセスをReactアプリケーションのページから開始するにはどうすればよいですか?

この投稿のタイトルに記載したすべてのアイテムではなく、ほとんどのアイテムに関連する投稿がかなり見つかりました。そして、私はこれを機能させるのにかなり近づいていますが、何かが欠けているに違いありません。

私のアプリは、ルーティングにreact-routerを使用したcreate-react-appフロントエンドで構成されています。私の開発環境では、これをポート51000で実行しています。 package.jsonでは、「proxy」を使用して他のルートをExpress Serverにリダイレクトし、ポート51001で実行しています。これは一般的に、サーバーにヒットするmy Reactコンポーネント内でリクエストを行うために機能します。 例えば:

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

My Reactコンポーネント内で呼び出すと、Expressサーバーが正常にヒットします。

私のバックエンドルートが認証されていることを確認したいのですが、passport-facebookを介してFacebook認証を使用することを選択しました。これは、これまでに見た多くのオンラインチュートリアルと同じように設定しました。たとえば、「/ auth/facebook」という名前のエクスプレスサーバー上のルートがあります。 localhost:51001/auth/facebookにアクセスすると、facebookにリダイレクトされてログインし、指定したルートにリダイレクトされます。したがって、そのフローは期待どおりに機能します。

私が抱えている特定の問題は、Reactを取得して、認証をトリガーするAPI呼び出しを正常に開始して完了することです。2つの方法を試しました。

アプローチ1:ajax経由でルートを呼び出す

私は私のcomponentDidMountで以下を呼び出しました:

axios.get('/auth/facebook')

これにより、Expressサーバーが正常にヒットしますが、すぐにブラウザコンソールに次のエラーが生成されます。

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:510 'はアクセスを許可されません。

**アプローチ2:ブラウザーでルートに移動する**

私が試したもう1つのことは、すべてのチュートリアルで見たことですが、認証ルートに移動するだけのページへのリンクを追加することです。例えば:

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

ただし、これをクリックすると、最終的に http:// localhost:51000/auth/facebook になるか、Reactアプリの空白ページが表示されます。私が持っているプロキシは作動せず、ブラウザでこのルートに移動してもExpressサーバーにアクティビティが表示されません。それは、react-routerで定義したルートではありません。

だから私はここで少し行き詰まっています。そのタグをクリックすると、そのルートがExpressサーバーに対して発動されますか?特定のルートを無視してExpressサーバーにリダイレクトするようにreact-routerに指示する方法はありますか?これはAJAX=呼び出しを行うときに正常に機能するようですが、localhost:51000/not/a/routeにアクセスしても、リクエストがExpressにリダイレクトされることはありません。ロードするだけです。コンテンツのない反応ページ。

どんな助けでもありがたいです。

おかげで、

-ダン

[〜#〜]編集[〜#〜]

ですから、これがうまく機能しているのは確かですが、「正しい」方法であるとはまったく確信していません。

私の反応アプリ(リコールはポート51000で実行されています)には、次のリンクがあります。

<a href="http://localhost:51001/auth/facebook">Facebook Login</a>

これは、反応ルートではなく、私のAPIサーバーを直接指していることに注意してください。このリンクに移動すると、高速サーバーにアクセスし、すぐにFacebookにリダイレクトされます。ログインすると、Express facebookのコールバックにリダイレクトされ、それ自体が http:// localhost:51000/somePage にリダイレクトされます。

理想的には、そのタグは、別のURL /ポートに移動するようにハードコーディングされているのではなく、/ api/auth/facebookに移動することになります。ロードする必要のあるページのように扱うのではなく、react-routerにパススルーさせる方法を見つけた場合は、この問題を更新します。

EDIT 2

私は他の人に他のことを言うことを受け入れますが、私の現在のアプローチは実際にはかなりうまくいくと思います。本番環境での動作を検討しました。私の反応サイトはwww.example.comにあり、Expressサーバーはapi.example.comからアクセスできます。 Facebookログインへのリンクは「api.example.com/auth/facebook」になります。コールバックは、認証が成功したと想定して、「www.example.com/some/route」にリダイレクトします。ログインを実行するために「api」URLにバウンスすることは合理的だと思います。最終的に、react-routerに特定のルートを無視させようとしても、私のAPI呼び出しはすべて明示的なルートに対して行われるため、意味がありません。

私は他の人に完全に役立つ解決策を提供していないことに気づきました。すべてをまとめたら、このログインフローを含む私のリポジトリへのリンクを含めます。

**編集3 **

ここに私のプロジェクトへのリンクがあります。プロジェクト全体を実行するのは簡単なことではありませんが、認証フローに関連付けられているファイルはほんの一握りです。

ここでリポジトリを表示できます: https://github.com/dan-goyette/Portfolio

このためのExpressサーバールーターは次のとおりです。

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

UIでは、次のコンポーネントを使用してExpressサーバーへの呼び出しをトリガーしています。

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

右上のボタンである https://www.dan-goyette.com/home で動作していることがわかります。

20
Dan

私もこの問題に遭遇していました-CRAプロキシ設定を変更するとうまくいくようです:

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

OAuthリンクは/api/auth/fooにあり、CRAアプリはlocalhost:3000にあり、Expressアプリはlocalhost:3001にあります。

2
romeboards

今日同じ問題に遭遇し、create-react-appのプロキシを使用せずに、バックエンドでcreate-react-appへのプロキシを設定することで解決しました。

私のエクスプレスアプリのendに、

 // 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でプロキシをオフにすることを忘れないでください。そうしないと、無限のプロキシループなどになる可能性があります。

Create react app localhostサーバーをWeb APIに追加するには、console.developers.google.comにアクセスして、create-react-app localhostを「Authorized JavaScript origins」と「Authorized redirect URIs」に追加します。

0
sumit

編集:私の以前の答えは問題とは関係がなく、解決しませんでした。私の場合の全体は、CLIで生成されたindex.jsのregisterServiceWorkerが原因でした。削除するだけで、すべてが正常に機能します。

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

registerServiceWorker();
0
Braulio Miki

Facebookログイン製品セクションのFacebook開発者設定の「有効なOAuthリダイレクトURI」フィールドを使用して、この問題を修正しました。たとえば、http://your-domain.loc:5000/auth/facebook

そして、Facebook Authボタンは次のようになります。

<a href="http://your-domain.loc:5000/auth/facebook">Login with Facebook</a>

FacebookリダイレクトURLをそこに配置する必要があります。私の例からもう1つ:ローカルノードサーバーには3000ポートを使用し、アプリのAPIリクエストには5000ポートを使用します。

私が使う /etc/hostslocalhostではなく、私のドメインを使用するため。

127.0.0.1   your-domain.loc

私のために働く。

また、GitHubリソースで追加の議論が行われています- https://github.com/facebook/create-react-app/issues/3502

0