ShaMoh ShaMoh -4 years ago 178
Node.js Question

NodeJS Express req[user] undefined on multiple refresh

My Question is similar to this.I am using express version 4.14.0 and I have implemented OAuth2 SSO using "passport-ping" module. For getting new Access token from refresh token which we have on successful login I am using "passport-oauth2-refresh" module. No problem with these modules. Everything works fine as expected. But the problem is with request.user object. Below is my code

var express = require('express');
var async = require('async');
var cookieParser = require('cookie-parser');
var request = require('request');
var passport = require('passport');
var OAuth2Strategy = require('passport-ping').Strategy;
var refresh = require('passport-oauth2-refresh');
var session = require('express-session');
var bodyParser = require('body-parser');
var Client = require('node-rest-client').Client;
var client = new Client();
var _outputpath = "/build",
_templatePath = "./templates";

var app = express();

app.use(express.static(__dirname + "/"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({
secret: "session secret",
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

var port = process.env.port || 8080;

// Allow cross orgin
app.all('*', function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token');
res.setHeader('Access-Control-Allow-Credentials', true);
if (req.method === 'OPTIONS') {
res.status(200);
res.end();
} else {
next();
}
});

passport.serializeUser(function (user, done) {
done(null, user);
});

passport.deserializeUser(function (id, done) {
done(null, id);
});

var strategy = new OAuth2Strategy({
authorizationURL: 'xxx',
tokenURL: 'xxx',
clientID: 'xxx',
clientSecret: 'xxx',
callbackURL: 'http://localhost:8080'
},
function (accessToken, refreshToken, profile, done) {
done(null, { accessToken: accessToken, refreshToken: refreshToken });
}
);

passport.use('oauth-provider', strategy);
refresh.use('oauth-provider', strategy);

var isAuthenticated = function (req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
res.redirect('/');
}
}

/***************** GET BASE PAGE ************/
app.get('/guide', isAuthenticated, function (req, res) {
async.series({
one: function (callback) {
newAccessToken(req, res, true, function (reqQuery) {
var _reqQuery = reqQuery;
res.cookie('userAccessToken', req["user"].refreshToken, { maxAge: 1 * 24 * 3600000, httpOnly: false });
res.sendFile(__dirname + _outputpath + '/index.html');
callback(null, req["user"]);
})
},
two: function (callback) {
callback(null, 2);
}
},
function (err, results) {
console.log('Completed Guide Page');
});
});

app.get('/', passport.authenticate('oauth-provider', {
successRedirect: '/guide',
failureRedirect: '/error',
pfidpadapterid: 'OAuthAdapterCCDS'
})
);

function newAccessToken(req, res, isParent, callback) {
refresh.requestNewAccessToken('oauth-provider', req["user"].refreshToken, function (err, accessToken, refreshToken) {
var expireAccessToken = new Date();
expireAccessToken.setMinutes(expireAccessToken.getMinutes() + 59);
req["user"].refreshToken = refreshToken;
req["user"].accessToken = accessToken;
req["user"].accessTokenTime = new Date();
req["user"].expireAccessToken = expireAccessToken;
callback(req);
});
}

/***************** START THE SERVER ************/
app.listen(port, function () {
console.log('Server started & listening on port: ' + port);
});


On successful login OAuth2Strategy done function is adding below object to req.user.

{ accessToken: accessToken, refreshToken: refreshToken }


On every request I am hitting newAccessToken function to get new Access token for refresh token we have and updating the req.user object with new Access token and refresh token manually as shown below. Is there any better way to update the req["user"]?

req["user"].refreshToken = refreshToken;
req["user"].accessToken = accessToken;
req["user"].accessTokenTime = new Date();
req["user"].expireAccessToken = expireAccessToken;


If the user hits refresh continuously from browser, I am getting as req.user undefined. Tried few things by seeing forum but it dint worked. Any help is much appreciated.

Answer Source

I dint handled the error properly while getting the new access token. I changed new Access token function as below

function newAccessToken(req, res, isParent, callback) {
refresh.requestNewAccessToken('oauth-provider', req["user"].refreshToken, function (err, accessToken, refreshToken) {
    var expireAccessToken = new Date();
    expireAccessToken.setMinutes(expireAccessToken.getMinutes() + 59);
    req["user"].refreshToken = refreshToken;
    req["user"].accessToken = accessToken;
    req["user"].accessTokenTime = new Date();
    req["user"].expireAccessToken = expireAccessToken;
    callback(req);
});
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download