Right now, when I visit my page at https://example.com and click login, it goes to https://example.com/auth/facebook, which then does the facebook stuff and ends up calling back http://example.com/auth/facebook/callback. I can't seem to get it to call back using the https scheme (but only when the request cycle started in https).
right now, when viewed through an https iframe (facebook canvas app), I get the error
[blocked] The page at 'https://apps.facebook.com/example/?fb_source=notification&ref=notif¬if_t=app_notification' was loaded over HTTPS, but ran insecure content from 'http://example.com/auth/facebook/callback?code=AQD5TUeTP…yXC0ZM8S45V2iTta629IaquCpAqVUbhAvNCFveaDBlbKg4J4#=': this content should also be loaded over HTTPS.
passport.use(new FacebookStrategy({
clientID: process.env.FB_CLIENT,
clientSecret: process.env.FB_SECRET,
callbackURL: "/auth/facebook/callback",
profileFields: ['id']
},...
app.get('/auth/facebook',
passport.authenticate('facebook', {
scope: ["read_stream"]
})
);
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
failureRedirect: '/#'
}),
function(req, res) {
res.redirect('/#');
});
I'm running this on heroku, where it handles the details on https.
EDIT Apparently node provides req.connection.encrypted with information as to whether the request is https. Since I am running on heroku behind nginx where that handles all of the https before node, req.connection.encrypted will always be undefined.
Still don't know how to solve this though.
I looked into the Passport Oauth2 strategy code and checked that it uses req.connection.encrypted to check if it is in a secure connection. It also checks for proxies in case the server code runs behind one. It is possible to tell passport to trust a proxy if you know that you are behind one.
It seems that since SSL is handled by nginx on Heroku, req.connection.encrypted is always "undefined". (groups.google.com/forum/#!topic/express-js/Bm6yozgoDSY) Nginx handles all of the HTTPS on Heroku so node never sees req.connection.encrypted being anything other than "undefined".
To solve the problem you have to tell passport to trust the proxy adding the line
app.enable("trust proxy");
to your express server.
I've also learned that we can accomplish the same thing by adding another property called "proxy:true" to the googleStrategy such as below:
passport.use(new GoogleStrategy({ clientID: keys.googleClientID, clientSecret: keys.googleClientSecret, callbackURL: '/auth/google/callback', proxy: true }
Nginx handles all of the HTTPS on Heroku so node never sees req.connection.encrypted being anything other than undefined. By digging through the passportjs repositories I found that there is a check for the app to have "trust proxy" enabled. To solve this problem, add the line
app.enable("trust proxy");
to your express server.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With