Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to handle passport-facebook callback in angular client?

I am developing a MEAN application. I am using passport for authentication- local, facebook and google strategies.

I am using angularjs client. All the routing is handled at client. I am only consuming server data apis.

When using passport-facebook strategy, I am using below code at node server as per passport docs.

    app.get('/auth/facebook',passport.authenticate('facebook-auth', { scope : ['email'] }));
    app.get('/auth/facebook/callback',passport.authenticate('facebook-auth', {
        successRedirect : '/home',
        failureRedirect : '/login',
        scope:['email']
    }));

Problem I am facing is when user click on "Sign in using Facebook" button

<a href="/auth/facebook" class="btn"><i class="fa fa-facebook"></i> Sign in using Facebook</a>

Client will access "/auth/facebook" route that will eventually redirect user to facebook page for validating user's credentials.

After successful validation, user will be redirected to route "/home" as defined in "successRedirect" value.

Now the thing is, I want to use custom callback function instead of defining redirects for success or failure. It will look like below:

app.get('/auth/facebook/callback',passport.authenticate('facebook-auth', function(err,user,info){
   if(err){
            throw err;
        }
        else if(user === 'userexists'){
            res.json({
                'state':false,
                'message':'User with this e-mail already exists'
            });
        }
        else{
            req.logIn(user,function(loginErr){
                if(loginErr){
                    throw loginErr;
                }
                res.json({
                    'state':true,
                    'message':'You logged in successfully!'
                });
            });
        }
 }));

The root problem I am facing here, I can not use above custom callback as Client is not calling the "auth/facebook/callback" route, it is called by facebook. So, there is no success handler waiting to catch above callback's response at client side!!

I want some way to get response in json form at client to eliminate server side redirection and also way to pass message and username to client after successful authentication by facebook.

I am about to give up with passport. Hoping for any possible solution before removing a lot of code!

Thanks

like image 847
mjaydip Avatar asked Jan 12 '16 14:01

mjaydip


1 Answers

This can be accomplished by redirecting to another endpoint inside the facebook callback handler. There is no need to do res.json() on the callback from facebook since they only make a request to that in order to let you know if auth failed or succeeded. From their docs:

// GET /auth/facebook/callback
//   Use passport.authenticate() as route middleware to authenticate the
//   request.  If authentication fails, the user will be redirected back to the
//   login page.  Otherwise, the primary route function function will be called,
//   which, in this example, will redirect the user to the home page.

So facebook returns control over request process back to you when they call /auth/fb/callback but it's up to you what to do next. Since once the user is successfully authenticated, you would have req.user available throughout the whole session. At this point, you can redirect to something like the have in the example /account and check if req.user with req.isAuthenticated() and complete the flow you desire.

like image 135
onel0p3z Avatar answered Oct 11 '22 19:10

onel0p3z