思えばEasyな問題だったんだけど、つまづいたもんはメモ。
そもそもやろうとしたこと
私はこんな感じのことがしたかった。
- 外部からはhttpsで独自取得してるドメイン宛にアクセスされる。(例:https://example.com )
- nginxでリバースプロキシ。外部からのアクセスはまずここに着く。(※別のドメインも運用してたので。)
- Node.js上で動くLoopback-facebook-passportを使って、Facebookログイン認証でログインする。
これを試すべく、サンプルプログラムを下記からゲットして動かしてみた。
https://github.com/strongloop/loopback-example-passport
この時、満足に設定もせずFacebookログインをしようとして困ったことから学んだ話をメモします。
困ったこと:CallbackアドレスがうまくFacebookに渡らない
しれっとつなぎにかかった時に、下記のようなエラーが出た。
指定されたURLは、アプリケーションの設定で許可されていません。: 指定されたURLの中にアプリの設定で認められないものが含まれています。ウェブサイトまたはキャンバスのURLと一致しているか、ドメインがアプリのドメインのサブドメインである必要があります。
回避策については、調べればいくつか出てきたけど、結局のところ、
Callbackアドレスがnginxで指定した宛先URL( http://192.168.0.1:3000 )になって返されていることに気づいた。
...redirect_uri=http%3A%2F%2F192.168.0.1%3A3000%2Fauth%2Ffacebook%2Fcallback...
期待するところは下記である。
...redirect_uri=https%3A%2F%2Fexample.com%2Fauth%2Ffacebook%2Fcallback...
Try①:nginxのリバースプロキシ設定の変更
もともとは下記のような設定をしていた
server {
listen 443 ssl;
server_name example.com;
ssl_certificate CERT_FILE;
ssl_certificate_key KEY_FILE;
access_log ACCESS_LOG;
error_log ERROR_LOG;
location / {
proxy_pass http://192.168.0.1:3000;
}
}
このうち、Location部分を下記の通り変更する。
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-HTTPS on;
proxy_set_header X-Forwarded-SSL on;
proxy_set_header HTTPS on;
proxy_set_header SSL on;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.0.1:3000;
}
※時間を見つけて、設定に追加したいろいろの意味も書いておきたいけど、今は省略
これにより、Callbackアドレスは下記のようになった。
...redirect_uri=http%3A%2F%2Fexample.com%2Fauth%2Ffacebook%2Fcallback...
Oh... 「https」じゃなく「http」じゃないか。。。
でも、そりゃそうだ。httpで繋いでるんだもんね。
最終的な対応:providers.jsonの変更
そりゃそうだ。もともと、ホスト部分は設定変更できないのかなって思ってたんですが、
下記のとおり、callbackURLの部分をアドレスフルパス指定すればよい。
"facebook-login": {
"provider": "facebook",
"module": "passport-facebook",
"clientID": "CLIENT_ID",
"clientSecret": "CLIENT_SECRET",
"callbackURL": "https://example.com/auth/facebook/callback",
"authPath": "/auth/facebook",
"callbackPath": "/auth/facebook/callback",
"successRedirect": "/auth/account",
"failureRedirect": "/login",
"scope": ["email"],
"failureFlash": true
これやっちゃえば、nginxの設定しなくてもよかった、というオチでした。
これに長く時間をかけちゃったことを反省したいと思います。。。