Question

I am using passportjs to allow user login via linkedin.

The required result is that I will get their email, name and last name

This is my code

exports.linkedInLogin = function( req, res, next ){

    var widgetId = req.params.widgetId;

    passport.use(new LinkedInStrategy({
            consumerKey: conf.linkedIn.apiKey,
            consumerSecret: conf.linkedIn.secretKey,
            profileFields: ['id', 'first-name', 'last-name', 'email-address', 'headline'],
            callbackURL: req.absoluteUrl('/backend/widgets/' + widgetId + '/login/linkedin/callback')
        },
        function(token, tokenSecret, profile, done) {
            logger.info('linkedin logged in success',arguments);
        }
    ));

    passport.authenticate('linkedin')( req, res, next );
};

exports.linkedInLoginCallback = function( req, res ){

    logger.info('linkedin login callback',req.query);
    res.send(req.query);
};

I have 2 questions

First Question

This function is never invoked - why?

function(token, tokenSecret, profile, done) {
        logger.info('linkedin logged in success',arguments);
}

Second Question

How should I get the user's email? I can't seem to find it anywhere.

EDIT :

After reading another Q/A I change the 'authenticate' line to

passport.authenticate('linkedin', { scope: ['r_basicprofile', 'r_emailaddress'] })( req, res, next );

and change callack to

exports.linkedInLoginCallback = function( req, res ){

    var request = require('request');
    logger.info(req.query.oauth_token);
    var options =
    {
        url: 'https://api.linkedin.com/v1/people/~/email-address',
//        url: 'https://api.linkedin.com/v1/people/~',
        headers: { 'x-li-format': 'json' },


        qs: { oauth2_access_token: req.query.oauth_token } // or &format=json url parameter
    };
    request(options, function ( error, r, body ) {
        logger.info('hello',error, body);
        res.send( { 'query' : req.query, 'error' : error, 'body' : body} );
        if ( r.statusCode != 200 ) {
            return;
        }
        try {
            logger.info(body);

        }
        catch (e) {
            return;
        }
    });

//    logger.info('linkedin login callback',req);

};

But I keep getting Invalid access token.

Was it helpful?

Solution

After a day of reading and tutorialing, it seems that the answer is much simpler than I thought.

There was one thing I had to change - and it seems I did not mention it in the question.

The route mapping to the callback.

Before, it was

app.get('/backend/widgets/:widgetId/login/linkedin/callback',controllers.widgetLogin.linkedInLoginCallback);

but it seems that if I simply add a middleware here

passport.authorize('linkedin')

so now it looks like this

app.get('/backend/widgets/:widgetId/login/linkedin/callback',    passport.authorize('linkedin'), controllers.widgetLogin.linkedInLoginCallback);

I get all the information I need on req.account. So my callback is now

exports.linkedInLoginCallback = function( req, res ){
    logger.info('linkedin login callback',req.account);
    res.send(200,req.account);
};

So all the magic relies on the callback's middleware!

Alternatively, if the routing is not under your control, you could change your callback to the following:

exports.linkedInLoginCallback = function( req, res ){
    passport.authorize('linkedin')(req, res, function(){
        logger.info('linkedin login callback',req.account);
        res.send(200,req.account);
    });
};

Which is my drug of choice.. seems like a simple function and callback without middleware cr%$.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top