Multiple facebook apps within 1 project


#1

Hi guys,

In my project, I need an option that allow users to integrate their own facebook app api.
So is there any way that I can use multiple facebook apps within 1 project?

I’m not sure if Meteor.loginWithFacebook has an option to manually config facebook_app_api and facebook_secret before sending request to facebook login.

Thanks for your helps!


#2

There’s (stupidly) no native solution in Meteor to do this, Meteor.loginWithFacebook won’t work for this use case. There are some package out there but they are all incomplete, not well maintained or don’t allow the fine control that you’ll likely want.

So I use PassportJs to do it. But that doesn’t work well out of the box with Meteor, so I’ve also added express and express-session and made it work with Meteor. Overall, it is a little complicated but with a bit of hacking you can get it done and then you can integrate all passport strategies :smile:

This is the general approach:

fbgraph = require 'fbgraph'
passport = require('passport')
FacebookStrategy = require('passport-facebook').Strategy
session = require('express-session')
import express from 'express';

app = express()

app.use(session({ 
  resave: false,
  saveUninitialized: true,
  secret: 'bla' 
  cookie : { secure: false }  
}));

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

passport.use(new FacebookStrategy(
    clientID: Meteor.settings.facebook.key,
    clientSecret: Meteor.settings.facebook.secret
    passReqToCallback: true    
    scope: ['manage_pages', 'user_friends', 'publish_pages', 'publish_actions']
    profileFields: ['id', 'displayName', 'friends', 'picture', 'email', 'accounts', 'likes']
    callbackURL: "#{getBaseUrl()}/auth/facebook/callback"    
  ,
    Meteor.bindEnvironment((req, accessToken, refreshToken, profile, done) =>
       ...
       # do whatever logic you want here, finally return the user
      done(null, user))


app.get '/auth/facebook/:userId/:projectId/:type', (req,res,next) ->
  # For facebook we pass userId and projectId as state
  # It cannot be on the callback route as the callback must be fixed
  passport.authenticate('facebook', { 
    authType: 'reauthenticate'    
    state: req.params.userId + "-" + req.params.projectId + "-" + req.params.type
  })(req,res,next)  


app.get '/auth/facebook/callback', (req, res, next) ->
  passport.authenticate('facebook', (err, user) =>
    # here we fetch the state and get the params we need
    [ userId, projectId, type ] = req.query.state.split('-')
    authRedirect(user, type, 'Facebook', err, res)
  )(req,res,next)

WebApp.connectHandlers.use(app)

#3

Thanks @satya for ur help
Sounds really complicated to me. I’ll try to find another solution before go with urs :smiley: