javabrain
javabrain

Reputation: 383

Facebook authentication callback to wrong server with AWS ELB elastic load balancer

Final Edit/Conclusion:

For the specific use case documented in section "context" below, the sticky sessions won't help. This points out the need for establishing a session before generating the authentication request. By setting up a page with a link to the route, the problem didn't reproduce.

Issue:

For multiple webservers under an AWS ELB elastic load balancer, a Facebook authentication callback may direct to a server other than issued the authentication request.

We're using node.js with passport for authentication.

Context:

Users were given a specific route (something like ourwebsite.com/dofbstuff ) and the handler for that route does a passport authenticate first thing:

    app.get( '/dofbstuff',
        passport.authenticate( 'facebook', {    
                            scope: [ 'email', <snip> 'publish_actions' ],
                            callbackURL:config.facebook.fbstuffCallback
                         } )

In this use case, the app works perfectly for one app server, but hangs with multiple servers.

Question:

What's the easiest way to solve this?

Potential solutions:

  1. On the app server, replace:
passport.use( new FacebookStrategy(...),function(accessToken){ etc. } )

with

  callTheAuthenticationServer( function(accessToken){ etc. } )
  1. (continued) and have the authentication server issue the auth request to Facebook (it resides on it's own DNS address for the call back) and issues a response to the app server. Then how will the req be forwarded to the authentication server to generate the Facebook login dialog on the client (user's browser)?

  2. Have the app server find out what port it's being forwarded from on the NAT. The ELB would need to accept a Facebook callback with that port in the URL (i.e. myserver.com/fbauthcallbackroute:portnumber ).

  3. https://aws.amazon.com/blogs/aws/aws-iam-now-supports-amazon-facebook-and-google-identity-federation/ claims "A similar flow can also be enabled for Facebook or Google identities by integrating their SDKs with your app and simply creating an additional role." I don't know if this means you can use Identity Federation as a means to obtaining a Facebook token. If so, where is this process documented?

Other notes:

I found this issue posted already here (in a ruby rails environment): Facebook Authentication + Load balancer

I have also logged a bug for passport-facebook on github here: https://github.com/jaredhanson/passport-facebook/issues/104

Upvotes: 1

Views: 1246

Answers (1)

ceejayoz
ceejayoz

Reputation: 179994

AWS ELBs have "sticky sessions", which will keep a particular user (via a cookie) on the same instance for the duration of their browsing session.

Another option is setting up a shared session store (AWS ElastiCache is perfect for this) so all servers store sessions in the same data store. That way, the user's session data isn't specific to an individual backend server.

Upvotes: 2

Related Questions