NodeJS Express req[user] 在多次刷新时未定义

Posted

技术标签:

【中文标题】NodeJS Express req[user] 在多次刷新时未定义【英文标题】:NodeJS Express req[user] undefined on multiple refresh 【发布时间】:2017-07-12 15:36:58 【问题描述】:

我的问题类似于this。我使用的是快速版本 4.14.0,并且我使用 "passport-ping" 模块实现了 OAuth2 SSO。为了从成功登录时我们拥有的刷新令牌获取新的访问令牌,我正在使用 "passport-oauth2-refresh" 模块。这些模块没有问题。一切都按预期正常工作。但问题在于 request.user 对象。下面是我的代码

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);
);

成功登录后,OAuth2Strategy 完成功能正在将以下对象添加到 req.user。

 accessToken: accessToken, refreshToken: refreshToken 

在每个请求中,我都会点击 newAccessToken 函数来获取我们拥有的刷新令牌的新访问令牌,并使用新的访问令牌和手动刷新令牌更新 req.user 对象,如下所示。有没有更好的方法来更新 req["user"]?

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

如果用户从浏览器连续点击刷新,我会得到 req.user 未定义。通过查看论坛尝试了一些事情,但它确实有效。非常感谢任何帮助。

【问题讨论】:

有什么更新吗?我面临着类似的情况 @PsycheGenie 在我的情况下,我努力正确处理错误,这是我面临问题的原因 【参考方案1】:

我在获取新的访问令牌时正确处理了错误。我更改了新的访问令牌功能如下

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);
);

【讨论】:

以上是关于NodeJS Express req[user] 在多次刷新时未定义的主要内容,如果未能解决你的问题,请参考以下文章

nodejs: express basic

nodejs: express basic

Nodejs express 获取url参数,post参数的三种方式

NodeJs中的express框架获取http参数

nodeJs学习-13 router

断言(req.assert)如何在nodejs中工作