Facebook Login is widely used as an authentication module on websites. Instead of asking user manual details such as email and password and then verify them, it’s better to use already verified user details.
In this article, we are going to learn and implement a Facebook Login System using Nodejs and ExpressJS. You can download the code by clicking the button below.
Table of Contents
Creating Facebook App:
Very first thing you going to need is AppIDย and AppSecretย from Facebook App. Please go to Facebook Developersย and create your app.
Choose Websiteย as platform when it ask. Give the proper name and you can leave the namespace field blank.
It will ask for Captcha, enter it carefully and once done it will redirect you to the app page. By authenticating your facebook account again you can view the App secret. Now go to Setting and add the Web as a platform.
If you want to test the app in localhostย environment then add localhost:3000ย as an site address.
The app is set. Let’s go ahead and create our App using Node.
Configuring our Node App:
In the source directory go to the configuration/config.jsย and update the Facebook AppID and AppSecret.ย If you want to use Database to store and validate user information you can put the configuration field as true or false. To know the database design for the app please visit twitter login using nodeย article.
"facebook_api_key" : "FB APP ID",
"facebook_api_secret" : "FB API SECRET",
"callback_url" : "http://localhost:3000/auth/facebook/callback",
"use_database" : false,
"host" : "localhost",
"username" : "root",
"password" : "",
"database" : "Database Name"
}
Update the code with Facebook App information.
Route of Our App:
Routes | Action |
---|---|
/auth/facebook | Authenticate User with Facebook |
/auth/facebook/callback | Get the user information from if login successfully |
/logout | Logging out from App. |
Configuring Passport:
I am using Passport node package for the OAuth authentication. It requires configuration of some parameters. Here is our Passport configuration code.
passport.use(new FacebookStrategy({
clientID: config.facebook_api_key,
clientSecret:config.facebook_api_secret ,
callbackURL: config.callback_url
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
//Check whether the User exists or not using profile.id
if(config.use_database) {
//Further code of Database.
}
return done(null, profile);
});
}
));
Complete Server Code:
Here is our app.js with complete routing and Passport code.
, passport = require('passport')
, FacebookStrategy = require('passport-facebook').Strategy
, session = require('express-session')
, cookieParser = require('cookie-parser')
, bodyParser = require('body-parser')
, config = require('./configuration/config')
, mysql = require('mysql')
, app = express();
//Define MySQL parameter in Config.js file.
const pool = mysql.createPool({
host : config.host,
user : config.username,
password : config.password,
database : config.database
});
// Passport session setup.
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
// Use the FacebookStrategy within Passport.
passport.use(new FacebookStrategy({
clientID: config.facebook_api_key,
clientSecret:config.facebook_api_secret ,
callbackURL: config.callback_url
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
//Check whether the User exists or not using profile.id
if(config.use_database) {
// if sets to true
pool.query("SELECT * from user_info where user_id="+profile.id, (err,rows) => {
if(err) throw err;
if(rows && rows.length === 0) {
console.log("There is no such user, adding now");
pool.query("INSERT into user_info(user_id,user_name) VALUES('"+profile.id+"','"+profile.username+"')");
} else {
console.log("User already exists in database");
}
});
}
return done(null, profile);
});
}
));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: 'keyboard cat', key: 'sid'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
app.get('/auth/facebook', passport.authenticate('facebook',{scope:'email'}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { successRedirect : '/', failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
app.listen(3000);
Designing our View:
Once user login we just have to show the values return from Facebook. Here it is.
Running our App:
Download the code and update the config.js with the Facebook app information. Then run
to install dependencies and then run app using
Visit localhost:3000 to view the app.
Login using your Facebook account and allow the app permission. After successful authentication, you will be redirected to your specified callback URL.
Conclusion
We learned how to use and implement Facebook login system using Passport module. We used to express to develop the web server and MySQL to store user information.
Further Study
Learn more!
Twitter Login Using Node and MySQL
Facebook Status Box using Node.js and MySQL
HTML5 Push Notification System Using Nodejs MySQL Socket.io
How to Replace All Occurrences of a String in JavaScript
Very on-point with your Node tutorials, Shahid, much obliged.
Curious as to how you were going to make the index, layout, and account .ejs views work together…
Well.. I downloaded your code and ran it. But “Hello undefined” is printed.
Can you guess what is wrong?
hey may b coz , the profile is object is returning like dz — >
profile goes here –> { id: ‘1478199245840060’,
username: undefined,
displayName: ‘App Dev Axy’,
name:
{ familyName: undefined,
givenName: undefined,
middleName: undefined },
gender: undefined,
profileUrl: undefined,
provider: ‘facebook’,
_raw: ‘{“name”:”App Dev Axy”,”id”:”1**********0″}’,
_json: { name: ‘App Dev Axy’, id: ‘1**********0’ } }
user —> { id: ‘1*********0’,
username: undefined,
displayName: ‘App Dev Axy’,
name:
{ familyName: undefined,
givenName: undefined,
middleName: undefined },
gender: undefined,
profileUrl: undefined,
provider: ‘facebook’,
_raw: ‘{“name”:”App Dev Axy”,”id”:”1**********0″}’,
_json: { name: ‘App Dev Axy’, id: ‘1**********0’ } }
so go back to ur application and navigate to views -> index.ejs
edit this –> Hello, . to —> Hello, .
hope this should fix ur issue ๐
Could you tell me how to inspect this returning result, please?
I do with console command as below:
app.get(‘/account’, ensureAuthenticated, function(req, res){
console.log(req.user);
res.render(‘account’, { user: req.user });
});
it returns:
2016-09-25T11:58:03.31+0700 [App/0] OUT { id: ‘10154xxxxxxxxxxxx’,
2016-09-25T11:58:03.31+0700 [App/0] OUT displayName: ‘Jeerapong Putthanbut’,
2016-09-25T11:58:03.31+0700 [App/0] OUT name: {},
2016-09-25T11:58:03.31+0700 [App/0] OUT provider: ‘facebook’,
2016-09-25T11:58:03.31+0700 [App/0] OUT _raw: ‘{“name”:”Jeerapong Putthanbut”,”id”:”10154623775144673″}’,
2016-09-25T11:58:03.31+0700 [App/0] OUT _json: { name: ‘Jeerapong Putthanbut’, id: ‘10154623775144673’ } }
I cant understand what you are saying to change. please be specific. I am also getting ‘Hello undefined’ as result.
try this Hello,
Not working.. says
Given URL is not allowed by the Application configuration: One or more of the given URLs is not allowed by the App’s settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App’s domains.
Its because either facebook app URL is wrong or you have set it to wrong on your config files.
In folder auth folder in not exits, and i am giving Hello,Undefind.
please help me.
Please post screen shot.
if you did not save your username then how facebook will show it to you then by default it shows undefined.
i also download your code but after accessing data from facebook it displayed HELLO,.
Did you updated Facebook app configuration ?
it displayed only hello,.
Hello! Awesome work sir! I just needed to know, what fields more to add, if we want to extract more than just the user id, like name, email, etc? (for both twitter and facebook login)
You can add lots of field as listed here in facebook app documentation.
How can the operations of MySql converted to that of mongoDB? If i want to store and retrieve my data from mongoDB, how can that be done?
Sir how to get the user profile pic download to server side
Hey,
I am not sure about it. But as far as i know you need extra permission to get user profile picture and that too you will get URL. So you need to write custom code to download that pic.
I wasted nearly one week for implementing this thing in maa project….
But Finally wen i found this module O:) #Made_my_day O:)
Thanx a ton broh u helped me #Twice …. #Shaid O:)
THanx Alot ๐ Plz keep on post’n ๐ will b supporting ur work ๐ #peace ! ๐
hi shahid, ur tutorial is osssome and i want to know how to get the users profile pic too..pls give me a quick response
Hey shahid,
can we get acess token of a user?
Yes you can. its in the req variable of router after successful authentication.
Nice article!!
Thank you so much ๐
This sql always returning 0, even if the number of rows is greater than 0 in MySQL database.
SELECT * from user_info where user_id=”+profile.id
Nice tutorial
exactly what I was looking for ๐
Is it still possible to use OAuth2 with facebook without having https ?
Because I’m trying this with localhost:8080/auth/facebook/callback and it doesn’t works…
I get an error while adding a new user: it tries to add a random id and “unverified” as a username…
Thanks
In admin panel of FB, remove http and just use localhost:8080…I have updated the comment too.
thanks for fast answer, I did this but I still have the app that crashes with this output (I added a console.log of the failing request)
https://i.goopics.net/G5W13.png
thanks for fast answer, I did this but I still have the app that crashes with this output (I added a console.log of the failing request)
https://i.goopics.net/G5W13.png
FacebookTokenError: Error validating client secret.
at Strategy.parseErrorResponse (C:\Users\Apple\Desktop\My_node_Programs\facebook-login-node-express-master\node_modules\passport-facebook\lib\strategy.js:196:12)
at Strategy.OAuth2Strategy._createOAuthError (C:\Users\Apple\Desktop\My_node_Programs\facebook-login-node-express-master\node_modules\passport-oauth2\lib\strategy.js:376:16)
at C:\Users\Apple\Desktop\My_node_Programs\facebook-login-node-express-master\node_modules\passport-oauth2\lib\strategy.js:166:45
at C:\Users\Apple\Desktop\My_node_Programs\facebook-login-node-express-master\node_modules\oauth\lib\oauth2.js:191:18
at passBackControl (C:\Users\Apple\Desktop\My_node_Programs\facebook-login-node-express-master\node_modules\oauth\lib\oauth2.js:132:9)
at IncomingMessage. (C:\Users\Apple\Desktop\My_node_Programs\facebook-login-node-express-master\node_modules\oauth\lib\oauth2.js:157:7)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1055:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
I am getting this error —>FacebookAuthorizationError: Can’t load URL: The domain of this URL isn’t included in the app’s domains. To be able to load this URL, add all domains and sub-domains of your app to the App Domains field in your app settings.
at Strategy.authenticate (C:\Users\Junia\Desktop\node\node_modules\passport-facebook\lib\strategy.js:81:23)
at attempt (C:\Users\Junia\Desktop\node\node_modules\passport\lib\middleware\authenticate.js:361:16)
at authenticate (C:\Users\Junia\Desktop\node\node_modules\passport\lib\middleware\authenticate.js:362:7)
at Layer.handle [as handle_request] (C:\Users\Junia\Desktop\node\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Junia\Desktop\node\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Junia\Desktop\node\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Junia\Desktop\node\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Junia\Desktop\node\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\Junia\Desktop\node\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\Junia\Desktop\node\node_modules\express\lib\router\index.js:275:10)
Thankyou so much , really helped me a lot , thanks man
i would like to see this a sequel to this article using https://www.npmjs.com/package/grant