Search code examples
javascriptangularjsnode.jstwitter

Sign in With Twitter using JWT, NodeJS and AngularJS


I'm having a big issue that I'm not sure is just a code design issue or I'm trying to do something that makes no sense.

I've implemented a local sign up using passport for authentication and JWT for route access and permissions. I send the token to the front end and save it to LocalStorage using AngularJS.

Everything there works and makes sense. But with twitter, I can't figure out how to implement the same strategy for getting the user logged in.

I've set up everything on the Twitter side, use passport for login and registering. But I don't see how it is possible to send the token to the front end because I can only use a GET request to receive the information from the Twitter API.

I redirect to Twitter login, redirect to the callback URL. But what comes after that? I have some relevant code that just returns the JWT. What I'm asking is how can I pass that to Angular in the best way possible?

Routes:

app.get('/login/twitter', passport.authenticate('twitter'));
app.get('/login/twitter/callback', function(req, res) {
    passport.authenticate('twitter' , function(err, user, info) {
        if(err) {
            res.json({
                'message': err
            });
        }
        var token;
        token = user.generateJwt();
        res.status(200);
        res.json({
            "token" : token
        });
    })(req, res);
});

Passport:

passport.use(new TwitterStrategy({consumerKey: auth.twitterAuth.consumerKey, consumerSecret: auth.twitterAuth.consumerSecret, callbackURL: auth.twitterAuth.callbackURL}, function(req, key, keySecret, profile, done) {
    User.findOne({'twitter.id' : profile.id}, function(err, user) {
        if(err) {
            return done(err);
        }
        if(user) {
            if(!user.twitter.token) {
                user.twitter.token = key;
                user.twitter.username = profile.username;
                user.twitter.displayName = profile.displayName;

                user.save(function(err) {
                    if(err) {
                        res.json({
                            'message': err
                        });
                    }
                    return done(null, user);
                });
            }
            return done(null, user);
        }
        let newUser = new User();

        newUser.twitter.id = profile.id;
        newUser.twitter.token = key;
        newUser.twitter.username = profile.username;
        newUser.twitter.displayName = profile.displayName;
        newUser.twitter.registerDate = Date.now();

        newUser.save(function(err) {
            if(err) {
                res.json({
                    'message': err
                });
            }
            return done(null, newUser);
        });
    });
}));

Solution

  • The best way to do this from my experience is to pass the information you want to store in the JWT to the url and store the token in localStorage on the callback page. Once the user identifier is stored in the browser, redirect to the desired page.