1

I am trying to create an android app which is similar to Tinder.

Until now, what I have is login with facebook and it workd like this: The user sends access token to my server (wrriten in node js), and then it authorized him using paspport-facebook-token library.

And now I need to create a database of users in using mongoose. How and where should I do it? How to save users if I have ONLY facebook login? I need to save the user base on what?

This is my server routes.js code:

    module.exports = function(app) {


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

    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(bodyParser.json());




    app.get('/', function(req, res) {

        res.end("Node-Android-Chat-Project"); 
    });




    passport.use(new FacebookStrategy({
            clientID: *****1246,
            clientSecret: "******",
            callbackURL: "http://localhost:8080/auth/facebook/callback"
        },
        function(accessToken, refreshToken, profile, done) {
            console.log("accesToken ", accessToken)
            console.log ("refreshToken", refreshToken)
            console.log ("profile", profile)
            user = {} // find or create a user in your database
            done(null, user)

        }
    ));

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

// Redirect the user to Facebook for authentication.  When complete,
// Facebook will redirect the user back to the application at
//     /auth/facebook/callback

    app.post('/auth/facebook/token', function(req, res, next) {
        passport.authenticate(['facebook-token'], function(err, user, info) {
            if (err) {
                return next(err); // will generate a 500 error
            }
            // Generate a JSON response reflecting authentication status
            if (! user) {
                console.log(req.user);
                return res.send({ success : false, message : 'authentication failed' });
            }
            console.log("Success!!");
                return res.send({ success : true, message : 'authentication succeeded' });
        })(req, res, next);
    });


    /*app.post('/auth/facebook/token',
        passport.authenticate('facebook-token'),
        function (req, res) {

            console.log(req)
            // do something with req.user
            res.send(req.user? 200 : 401);
        }
    ); */
    //app.get('/auth/facebook', passport.authenticate('facebook'));

//app.get(, );

// Facebook will redirect the user to this URL after approval.  Finish the
// authentication process by attempting to obtain an access token.  If
// access was granted, the user will be logged in.  Otherwise,
// authentication has failed.
    app.get('/auth/facebook/callback',
        passport.authenticate('facebook', { successRedirect: '/',
            failureRedirect: '/login' }));


    passport.serializeUser(function(user, done) {
        done(null, user);
    });

    passport.deserializeUser(function(user, done) {
        done(null, user);
    });

};

2 Answers2

2

You are almost ready, all you need to do now is save that user in your db. I use a nifty little plugin for mongoose called findOneOrCreate which provides a shortcut method for doing a findAndModify it actually does consecutive find and create (check out this stack overflow answer for a real findAndModify. You can use the upsert option to get this behaviour)

The following code will initialize the User mongoose schema. Put it in your init section of the node js server.

var mongoose = require('mongoose');
var findOneOrCreate = require('mongoose-find-one-or-create');
var User = new mongoose.Schema({
    facebookId: {
        type: 'String',
        unique: true,
        sparse: true
    },
    firstName: {
        type: 'String',
        match: mongo.nameRegex
    },
    lastName: {
        type: 'String',
        match: mongo.nameRegex
    },
    birthday: {type: 'Date'}
}, { collection: 'users' });
User.plugin(findOneOrCreate);

Then use this code:

passport.use(new FacebookStrategy({
        clientID: *****1246,
        clientSecret: "******",
        callbackURL: "http://localhost:8080/auth/facebook/callback"
    },
    function(accessToken, refreshToken, profile, done) {
        console.log("accesToken ", accessToken)
        console.log ("refreshToken", refreshToken)
        console.log ("profile", profile)
        var user = {
             facebookId: profile.id,
             firstName: profile._json.first_name,
             lastName: profile._json.last_name,
             birthday: profile._json.birthday
        };
        //the same User variable from above
        User.findOneOrCreate({facebookId: profile.id}, user, function (err, user) {
             return done(err, user, {type: 'facebook'});
        });
    }
));

After that in your route handlers you will have access to the user that is currently authenticated in the req.user.

Ex:

app.get('/me', passport.authenticate('facebook-token'), function(req, res) {
    res.status(200).send(req.user);
});
Community
  • 1
  • 1
asotirov
  • 36
  • 5
  • Thanks! Why your Ex. code will return the current user? –  Aug 12 '15 at 14:27
  • Check out passport [authenticate](http://passportjs.org/docs/authenticate). I missed the bit where you need to _protect_ the `/me` endpoint. – asotirov Aug 12 '15 at 15:23
0

Facebook login has moved to a new GraphQL api. You can see how to integrate Facebook login with a Node.js server here: https://medium.com/authpack/facebook-auth-with-node-js-c4bb90d03fc0

Jack
  • 537
  • 5
  • 4