Welcome folks today in this blog post we will be building a facebook login authentication
using express and mongodb
in Passport. All the full source code of the application is shown below.
Get Started
In order to get started you need to install the below commands to create a new node.js
project as shown below
npm init -y
This will initialize a new node.js
project and make a new package.json
file as shown below
Now we need to install the below libraries using the below
command as shown below
npm i express
npm i passport
npm i mongoose
npm i passport-facebook
npm i ejs
And after that you need to make an index.js
file and copy paste the following code
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const express = require('express') const app = express() app.set("view engine","ejs") app.get('/',(req,res) => { res.render("index") }) app.listen(5000,() => { console.log("App is listening on Port 5000") }) |
And as you can see in the above code we are starting a basic express
app at the port number 3000
and also we are showing the index.ejs
template when we load the /
homepage route.
Now we need to create the views
folder and inside it we need to create the index.ejs
file and copy paste the below code
views/index.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<!-- views/index.ejs --> <!doctype html> <html> <head> <title>Node Authentication</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css --> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome --> <style> body { padding-top:80px; } </style> </head> <body> <div class="container"> <div class="jumbotron text-center"> <h1><span class="fa fa-lock"></span> Node Authentication</h1> <p>Login or Register with:</p> <a href="/auth/facebook" class="btn btn-primary"><span class="fa fa-facebook"></span> Facebook</a> </div> </div> </body> </html> |
Making Connection to MongoDB
Now guys we will be making the connection to the mongodb
database and for this we will be creating the models
folder and inside it create the User.js
file and copy paste the below code
models/User.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const mongoose = require("mongoose"); mongoose.connect("mongodb://localhost:27017/facebookauth", { useNewUrlParser: true, useUnifiedTopology: true, }); var userSchema = mongoose.Schema({ uid: String, token: String, email: String, name: String, gender: String, pic: String }); module.exports = mongoose.model('User', userSchema); |
As you can see we are importing the mongoose
library and then we are using the connect()
method to connect to mongodb database using the connection
string and then we are also creating the userSchema
and inside it we have the userid, and then we have the token
and we are storing the name
,email and gender and pic of the user.
And now we need to update the index.js
file with the below code. And inside this we will be importing the models/User.js
file as shown below
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
const express = require('express') const app = express() const passport = require('passport') const cookieParser = require('cookie-parser') const session = require('express-session') const User = require('./models/User') const facebookStrategy = require('passport-facebook').Strategy app.set("view engine","ejs") app.use(session({ secret: 'ilovescotchscotchyscotchscotch' })); app.use(passport.initialize()); app.use(passport.session()); app.use(cookieParser()); passport.use(new facebookStrategy({ // pull in our app id and secret from our auth.js file clientID : "603496006962121", clientSecret : "c63a6f6f8189ed75b5958b2c0c0e7341", callbackURL : "http://localhost:5000/facebook/callback", profileFields: ['id', 'displayName', 'name', 'gender', 'picture.type(large)','email'] },// facebook will send back the token and profile function(token, refreshToken, profile, done) { // asynchronous process.nextTick(function() { // find the user in the database based on their facebook id User.findOne({ 'uid' : profile.id }, function(err, user) { // if there is an error, stop everything and return that // ie an error connecting to the database if (err) return done(err); // if the user is found, then log them in if (user) { console.log("user found") console.log(user) return done(null, user); // user found, return that user } else { // if there is no user found with that facebook id, create them var newUser = new User(); // set all of the facebook information in our user model newUser.uid = profile.id; // set the users facebook id newUser.token = token; // we will save the token that facebook provides to the user newUser.name = profile.name.givenName + ' ' + profile.name.familyName; // look at the passport user profile to see how names are returned newUser.email = profile.emails[0].value; // facebook can return multiple emails so we'll take the first newUser.gender = profile.gender newUser.pic = profile.photos[0].value // save our user to the database newUser.save(function(err) { if (err) throw err; // if successful, return the new user return done(null, newUser); }); } }); }) })); passport.serializeUser(function(user, done) { done(null, user.id); }); // used to deserialize the user passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); app.get('/profile', isLoggedIn, function(req, res) { console.log(req.user) res.render('profile', { user : req.user // get the user out of session and pass to template }); }); // route middleware to make sure function isLoggedIn(req, res, next) { // if user is authenticated in the session, carry on if (req.isAuthenticated()) return next(); // if they aren't redirect them to the home page res.redirect('/'); } app.get('/auth/facebook', passport.authenticate('facebook', { scope : 'email' })); app.get('/facebook/callback', passport.authenticate('facebook', { successRedirect : '/profile', failureRedirect : '/' })); app.get('/',(req,res) => { res.render("index") }) app.listen(5000,() => { console.log("App is listening on Port 5000") }) |
As you can see we are authenticating the user
using passport-facebook library and after successfully authenticating we are redirecting
the user to the /profile
route And also we are passing the user
information to the profile template. And then we are applying the passport
authentication middleware and then serializing and deserializing the user.
And now we need to make the profile.ejs
template inside the views
folder as shown below
views/profile.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!-- views/profile.ejs --> <!doctype html> <html> <head> <title>Node Authentication</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <style> body { padding-top:80px; word-wrap:break-word; } </style> </head> <body> <div class="container"> <div class="page-header text-center"> <h1><span class="fa fa-anchor"></span> Profile Page</h1> <a href="/logout" class="btn btn-default btn-sm">Logout</a> </div> <div class="row"> <!-- FACEBOOK INFORMATION --> <div class="col-sm-6"> <div class="well"> <h3 class="text-primary"><span class="fa fa-facebook"></span> Facebook</h3> <p> <strong>id</strong>: <%= user.uid %><br> <strong>token</strong>: <%= user.token %><br> <strong>email</strong>: <%= user.email %><br> <strong>name</strong>: <%= user.name %><br> <strong>gender</strong>: <%= user.gender %><br> <img src="<%=user.pic%>" width="200" height="200" alt=""> </p> </div> </div> </div> </div> </body> </html> |
As you can see inside the above template we are rendering the user
information with the help of the ejs
we are rendering the user id
name, email and gender as shown below
And now we will be writing the simple get
request to logout the user from this app as shown below
1 2 3 4 |
app.get('/logout', function(req, res) { req.logout(); res.redirect('/'); }); |