【发布时间】:2017-09-13 05:15:11
【问题描述】:
我需要一些帮助来设置 Passport 消费者策略并将其集成到“本地人”中(现在,我们的本地策略运行良好)。我们尝试了几种方法,但没有成功 100% 工作。下面的代码不是完整的代码,我们已经删除了一些,所以这篇文章不会太长。对此的任何帮助将不胜感激。如果有人能让我们克服这个障碍,也可能会得到补偿。
所以一个问题是,如果用户通过消费者密钥和秘密进行身份验证,Passport 如何存储会话变量以便在整个站点中使用它们?
第二个问题,用户通过认证后我们如何处理?
- 本地和消费者都需要工作。
- 使用提供者的 POST 的消费者密钥和秘密
- 这只能是 OAuth1,到目前为止,OAuth2 不是一个选项。
- 这用于单点登录身份验证。
- 如果需要,我可以提供消费者会话输出。
最终,我们希望本地策略和消费者策略使用相同的“本地”全局变量。据我所知,我们可以对消费者进行身份验证,从数据库中检索用户,创建会话并判断用户是否“ensureAuthenticated”。
这是我们现在正在做的工作。
本地策略正在正确验证。
我们使用这些局部变量呈现页面: "省略了大部分代码以节省时间。"
//=================================================================
// The Authentication Module will bind to POST /login route
//=================================================================
authentication.initLocalStrategyRoutes(app);
passport.authenticate('local', {successReturnToOrRedirect: '/', failureRedirect: '/login'});
...
function renderPage(req, res, pageName, pageTitle){
res.render(pageName, {
pageName: pageTitle,
username: req.user ? req.user.username : '',
...
消费者策略是通过来自“提供者”的 POST 请求进行身份验证
我们已尝试将 Consumer 策略添加到身份验证中。
server.js
//=================================================================
// The Authentication Module will bind to POST /login route
//=================================================================
authentication.initLocalStrategyRoutes(app);
ADDED -> authentication.initConsumerStrategyRoutes(app);
passport.authenticate('local', {successReturnToOrRedirect: '/', failureRedirect: '/login'});
ADDED -> passport.authenticate('consumer', {successReturnToOrRedirect: '/', failureRedirect: '/login'});
authentication.js(省略代码)
module.exports = function(siteConfig, defaultRedirectPage, server, sessionStore, log) {
var passport = require('passport')
...
, ConsumerStrategy = require('passport-http-oauth').ConsumerStrategy
, TokenStrategy = require('passport-http-oauth').TokenStrategy
, LocalStrategy = require('passport-local').Strategy;
var auth = {};
var authenticationRedirects = { successRedirect: '/', failureRedirect: '/login' };
passport.serializeUser(function(user, done) {done(null, user);});
passport.deserializeUser(function(obj, done) {done(null, obj);});
auth.authenticate = function(email, password, callback) {
email = email.toLowerCase();
userController.findUserByUsernameWithPermissions(email,
function(err, user) {
if (err) return callback(err);
if (!user) return callback(null, null, 'Incorrect username.');
bcrypt.compare(password, user.password_hash, function(err, res) {
if(err){return callback(err);
} else if (!res) {return callback(null, null, 'Incorrect password.');
} else {if (user.account_state>0) {callback(null, user);} else {return callback(null, null, '/reset?rand='+user._id);}}
});
}
);
}
auth.initLocalStrategyRoutes = function(app){
passport.use(new LocalStrategy(auth.authenticate));
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) return next(err);
if (!user) return res.send({success: false, message: info});
req.logIn(user, function(err) {
if (err) { return next(err); }
res.send(req.user);
});
}) (req, res, next);
});
}
auth.initConsumerStrategyRoutes = function(app){
// passport.use(new LocalStrategy(auth.authenticate));
console.log('app: ', app)
passport.use('consumer', new ConsumerStrategy(
function(key, done) { console.log('starting ConsumerStrategy');
dbConsumerKey.findByConsumerKey({consumerKey: key}, function(err, consumerKey) {
if (err) { return done(err); }
if (!consumerKey) {
var errCode = dbError.find({name:'no_resource_link_id'}, function(err, errorCodes) {
console.log('statusText: ', errorCodes[0]["statusText"]);
return errorCodes[0]["statusText"];
});
return done(null, errCode);
} else {
if (!consumerKey[0]["consumerKey"]) { return done(err); }
if (!consumerKey[0]["consumerSecret"]) { return done(err); }
// return done(null, consumerKey[0]["consumerKey"], consumerKey[0]["consumerSecret"]);
return done(null, consumerKey[0], consumerKey[0]["consumerSecret"]);
}
});
},
function(requestToken, done) {
dbRequestTokens.find(requestToken, function(err, token) {
console.log('inside requestToken');
if (err) { return done(err); }
var info = { verifier: token.verifier,
clientID: token.clientID,
userID: token.userID,
approved: token.approved
}
done(null, token.secret, info);
});
},
function(timestamp, nonce, done) {
done(null, true)
}
));
};
auth.initTokenStrategyRoutes = function(app){}
auth.addUser = function(username, email, password, callback){auth.authenticate(username, "pass", callback);}
return auth;
};
authentication.js 策略确实验证了消费者密钥和秘密。但它不会创建我们想要的会话变量。我们希望消费者策略代码位于 authentication.js 文件中。
现在这是另一种方法,我们创建了一个名为 consumerkey.js 的单独文件
这个方向在一定程度上起作用。我们可以在屏幕上或命令行上输出护照会话。
var passport = require('passport')
exports.launchLti = [
passport.authenticate('consumer', { session: false/true [tried both] }),
function(req, res) {
db.findByStudentUserId({lis_person_contact_email_primary:
req.body.lis_person_contact_email_primary}, function(err, user) {
req.logIn(user, function(err) {
req.user.username = user[0].lis_person_contact_email_primary;
...
// req.session.save(function(){
// res.redirect('/classes');
res.redirect(200,'/');
// });
});
})
// res.render('launch', {launch: launch});
}
}]
【问题讨论】:
标签: node.js session express authentication passport.js