Crowdbotics Logo

Customers arrow

Don’t take our word for it, see what our customers have to say.

About Us arrow

We are on a mission to radically transform the software development lifecycle.

Home Blog ...

App Development

Add Instagram Login To Your NodeJS App Using PassportJS

Today, we will learn how to add the Instagram login to a NodeJS application using PassportJS (one of the most popular way to manage authentication in NodeJs). We will learn how Instagram’s APIs works…

6 October 2021

by Gaurav Agrawal

Learn how Instagram’s API works with Oauth, and implement the full login flow using MongoDB.

How does Instagram login work?

Instagram uses Oauth2.0 for authentication and authorization. Instagram login can be implemented for conventional apps and serverless apps. We will quickly look into both methods.

As per standard Oauth2.0, Instagram API needs an access_token for authentication. These access_tokens are specific to a user and time-bound. So when they expire in future, you need to ask for a refresh token.

Below are the three simple steps to get an access_token for Instagram:

1- Direct user to Instagram authorization URL.

2- User logs in (if not already logged in) and grant permissions to access Instagram data.

3- Instagram will redirect the call to your specified URL with a code parameter where you will exchange this code with an access_token on the server side.

For serverless apps, Instagram will add access_token in the redirect URL. (This is a less secure method and not is recommended).

Pre-requisite

Register an App with Instagram

Before moving forward, we need to register a client with Instagram.

Go to the Instagram developer console and create a new client app. Once you register, you will get a clientID and clientSecret.

Most likely, you will use a localhost for developing this. While registering you need to add a redirect URL. Mine was,

http://localhost:3000/auth/instagram/callback

You can choose your own, just remember, if you are using localhost and port 3000 (default NodeJs port) your URL should start with [http://localhost:3000](http://localhost:3000/auth/instagram/callback).

Captcha problem

While registering a new client app, you might face a captcha problem. To solve that, you can use the Diable Content Security plugin.

Login using Instagram

We will use passport.js, PasspostJS is a go-to library to implement different types of authentications into your application. It’s a middleware for your NodeJs app.

Let’s create an express app using.

express insta-auth

For simplicity, add the following code in app.js. You can refactor it once you understand the flow.

Install passpost-instagram

npm install passport-instagram

Import necessary files

var Instagram = require('passport-instagram');const InstagramStrategy = Instagram.Strategy;

Initialize Passport JS

We will now initialize PassportJs. If your application uses session (most probably it does) then you need to use passport session too. PassportJS will serialize and deserialize user instances to and from the session. Make sure to use express.session() before passport.session() to ensure that the login session is restored in the correct order.passport.session() alters the req object and change the ‘user’ value that is currently the session id (from the client cookie) into the deserialized user object. In case of logout, passportJs simply removes users information using deserializeUser.

app.use(passport.initialize());app.use(passport.session());
passport.serializeUser((user, done) => {done(null, user)})passport.deserializeUser((user, done) => {done(null, user)})

Passport Instagram Strategy

Different application such as Instagram, Twitter or Google can have different authentication methods. PassposJS bundles different authentication mechanisms into modules which are called as strategies. We are using Instagram strategy for our application.

To configure Instagram strategy we will add clientID, clientSecret, callbackURL and also pass a callback method to handle the authentication.

passport.use(new InstagramStrategy({clientID: "YOUR_CLIENT_ID",clientSecret: "YOUR_CLIENT_SECRET",callbackURL: "YOUR_CALL_BACK_URL"}, (accessToken, refreshToken, profile, done) => {
}))

We are using a database(MongoDB) to save our user’s information and access_token. You will check in your database if User already exists or not and create a new entry for new users.

passport.use(new InstagramStrategy({
  clientID: "YOUR_CLIENT_ID",
  clientSecret: "YOUR_CLIENT_SECRET",
  callbackURL: "YOUR_CALL_BACK_URL" 
}, (accessToken, refreshToken, profile, done) => {
 
}))
We are using a database(MongoDB) to save our user’s information and access_token. You will check in your database if User already exists or not and create a new entry for new users.

passport.use(new InstagramStrategy({
  clientID: "YOUR_CLIENT_ID",
  clientSecret: "YOUR_CLIENT_SECRET",
  callbackURL: "YOUR_CALL_BACK_URL" 
}, (accessToken, refreshToken, profile, done) => {
  User.findOne({ 'instagram.id': profile.id }, function(err, user) {
    if (err) return callback(err);
if (user) {
      return done(null, user); // Check if user already exists
    }
const {
      id,
      full_name,
      username,
      profile_picture,
      bio,
      website,
      counts: { media, follows, followed_by }
    } = profile._json.data;
const new_user = new User({ 
      instagram: {
        id,
        accessToken,
        full_name,
        username,
        profile_picture,
        bio,
        website,
        counts: {
          media,
          follows,
          followed_by
        }
      }
    });
new_user.save(function(err, user) { //saving a new user into mongo
      if (err) {
        throw err;
      }
      return done(null, user);
    });
  });
}))

Routes Configuration

Now we will configure some routes to create a login flow.

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

We will hit /auth/instagram in our application to initiate authentication flow in our application. This will initiate our Instagram authentication by redirecting the user to Instagram(If not already logged In).

Under the hood

Let’s see what’s happening under the hood? Once you call the passport authentication, it will go to Instagram, once user finished, Instagram will hit our callback URL with a code, this code will be exchange for access_token on the server side by PassportJS. If we don’t use passportJS, we need to do this ourself. PassportJS is internally performing authorization and authentication for us.

Once PassportJS will get the access_token, our callback method which is instagramInit in our, case will be called to complete the login process.

const instaConfig = {
    clientID: CLIENT_ID,
    clientSecret: CLIENT_SECRET,
    callbackURL: CALLBACK_URL
};
const instagramInit = function(accessToken, refreshToken, profile, callback) {
    User.findOne({
        'instagram.id': profile.id
    }, function(err, user) {
        if (err) return callback(err);
if (user) {
            return callback(null, user); // Check if user already exists
        }
const {
            id,
            full_name,
            username,
            profile_picture,
            bio,
            website,
            counts: {
                media,
                follows,
                followed_by
            }
        } = profile._json.data;
const new_user = new User({
            instagram: {
                id,
                accessToken,
                full_name,
                username,
                profile_picture,
                bio,
                website,
                counts: {
                    media,
                    follows,
                    followed_by
                }
            }
        });
new_user.save(function(err, user) {
            if (err) {
                throw err;
            }
            return callback(null, user);
        });
    });
};
passport.use(new InstagramStrategy(instaConfig, instagramInit));

Here we are are checking if we have user already in our database or not, If user doesn’t exist we will create a user and pass a callback to PassportJS, which then serialize and deserialize the request and internally forward the request to /profile.

app.get('/profile', ensureAuthenticated, (request, response) => {
const { instagram } = request.user;
response.render('profile', { user: instagram });
});

We will call ensureAuthenticated first once we hit /profile. Let’s see our ensureAuthenticated method. This method is simply checking that if the request is authenticated or not.

function ensureAuthenticated(request, response, next) {
   if (request.isAuthenticated()) {
   return next();
}
response.redirect('/');
}

This is our full flow. We will also implement a profile method to show the user’s information and a logout method.

app.get('/profile', ensureAuthenticated, (request, response) => {
  const { instagram } = request.user;
  response.render('profile', { user: instagram });
});
app.get('/logout', function(req, res) {
  req.logout();
  res.redirect('/');
});

Full working code

You can check the full code here.

You need to add rename config-template.json to config.json and add your credentials and also add a mongo URL. You can use mLab for using a cloud mongo.

Conclusion

You don’t need to use PassportJS for this purpose but it’s one of the most famous library in the node ecosystem with more than 120k downloads weekly. It provides more than 500 strategies for authentication, hence become an all-around solution for your authentication management.

Show us what you’re building in the comments ,and let us know if you get stuck somewhere and we will happy to help you out.

Extra sauce (Instagram Private APIs)

Apart from official APIs to integrate your application with Instagram developers created their own libraries to work with Instagram without using official APIs. (Instagram APIs were very poor in the beginning, so many developers created workarounds). You can check out some examples here and here.

Notes

Instagram started deprecating its API support and the current version of API will be fully deprecated till 2020 . You can access Instagram API’s through the Facebook developer portal, though they are currently supporting only business accounts. Also, Instagram recently launched Instagram Graph API (access through the Facebook developer portal).