jaredhanson / passport-facebook

Facebook authentication strategy for Passport and Node.js.
https://www.passportjs.org/packages/passport-facebook/?utm_source=github&utm_medium=referral&utm_campaign=passport-facebook&utm_content=about
MIT License
1.29k stars 446 forks source link

failureRedirect doesn't redirect as expected #255

Open roy-key opened 5 years ago

roy-key commented 5 years ago

Hi. As i'm trying to handle where a user clicks 'Cancel' on the Facebook prompted modal, instead of being redirect to the failureRedirect, I'm getting this:

FacebookAuthorizationError: Login Error: There is an error in logging you into this application. Please try again later.
    at Strategy.authenticate (/sample-app/node_modules/passport-facebook/lib/strategy.js:79:23)
at attempt (/sample-app/node_modules/passport/lib/middleware/authenticate.js:361:16)
at authenticate (/sample-app/node_modules/passport/lib/middleware/authenticate.js:362:7)
at Layer.handle [as handle_request] (/sample-app/node_modules/express/lib/router/layer.js:95:5)
at next (/sample-app/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/sample-app/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/sample-app/node_modules/express/lib/router/layer.js:95:5)
at /sample-app/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/sample-app/node_modules/express/lib/router/index.js:335:12)
at next (/sample-app/node_modules/express/lib/router/index.js:275:10)

The URL is which displays this error trace:

http://localhost:3000/auth/facebook/callback?error_code=1349003&error_message=Login+Error%3A+There+is+an+error+in+logging+you+into+this+application.+Please+try+again+later.#_=_

This is my settings (very similar to the example in the documentation: http://www.passportjs.org/docs/facebook/

This is my sample: server.js

const express = require('express');
const app = express();

const passport = require('passport')
    , FacebookStrategy = require('passport-facebook').Strategy;

app.use(passport.initialize());
app.use(passport.session());

passport.use(new FacebookStrategy({
        clientID: FACEBOOK_APP_ID,
        clientSecret: FACEBOOK_APP_SECRET,
        callbackURL: 'http://localhost:3000/auth/facebook/callback'
    },
    function (accessToken, refreshToken, profile, done) {
        done(null, profile);
    }
));

passport.serializeUser(function (user, done) {
    console.log('we are calling serialized user, user to serialized:');
    console.log(user);
    done(null, 'this is the user');
});

passport.deserializeUser(function (id, done) {
    console.log('we are calling de serialized user, user to de serialized:');
    console.log(id);
    done(err, {message: 'this is the user'});
});

app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/callback',
    passport.authenticate('facebook', {
        successRedirect: '/success',
        failureRedirect: '/failure'
    }));

const path = require('path');

app.get('/login', function (req, res) {
    res.sendFile(path.join('/sample-app/lib/login.html'));
});

app.get('/success', function (req, res) {
    res.sendFile(path.join('/sample-app/lib/success.html'));
});

app.get('/failure', function (req, res) {
    console.log("We have failed you");
    res.redirect('/login');
});

app.listen(3000, () => {
    console.log("I'm listening!");
});

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/auth/facebook">Login with Facebook</a>
</body>
</html>

success.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Success with facebook!</h1>
    <a href="/auth/facebook">Login with Facebook</a>
</body>
</html>

Running on:

dockerfile:
FROM-> node:10.2.1-slim
* cat /etc/issue => Debian GNU/Linux 8 \n \l
* cat /etc/debian_version=> 8.10

NPM
express : 4.16.3
passport: 0.4.0
passport-facebook: 2.1.1

Expected: be redirected to localhost:3000/failure [ notice, the successRedirect working great, i'm redirected to http://localhost:3000/success#_=_]

Notice: the example here: https://github.com/passport/express-4.x-facebook-example produces the same outcomes.

stelmakhivan commented 5 years ago

Try to config https server for your app

zuqini commented 4 years ago

I am having the same problem. The error is not forwarded to the failureHandler if the user presses cancel("Not now"). Is there any workarounds for this scenario?

SvetoslavHalachev commented 4 years ago

Did someone found a solution to this issue? Does https fix the failureRedirect?

Here is the issue on my side:

When I enter invalid code in the callback for example http://localhost:3000/auth/facebook/callback?code=some_invalid_code

I'm not redirected to the failureRedirect link but instead, an error with status 500 is thrown and a message which says FacebookTokenError: Invalid verification code format.. I want to show this message on the login page.

OsoianMarcel commented 4 years ago

@shalachev I have same problem on HTTPS. In my opinion the HTTP(s) protocol does not matter.

OsoianMarcel commented 4 years ago

These errors are passed via "next(err)" function (which is part of express js functionality). I think we need to treat them as exceptions, because failureRedirect is not used.

So, to catch them before main expressjs error handler middleware (err, req, res, next), we can catch them by passing error handler as next route function.

Sorry for my bad English.

For example:

const facebookCallback = passport.authenticate('facebook', {successRedirect: '/?pass', failureRedirect: '/?fail'});
const passportErrorHandler = (err, req, res, next) => {
    // Here you can handle passport errors
    console.error(`Passport error: ${err.message}`);
    res.redirect('/');
};

router.get('/facebook/callback', facebookCallback, passportErrorHandler);
UserGalileo commented 3 years ago

@roy-key Have you got any idea about the error you were getting from FB? I'm talking about the error 1349003. It's driving me nuts!! It appears that I get that error ONLY IF the user un-checks ONLY SOME of its groups from the permissions list. And the strange thing is that after that, if the user tries to login again, the app gets automatically authenticated with ALL permissions in all groups! What the hell!