我遇到的问题是没有设置req.user。我已经实现了findUserById函数,我有一个' id'属性在我的用户对象上。
这是我的app.js:
var express = require('express');
var everyauth = require('./middleware/everyauth.js');
var authorize = require('./middleware/authorize.js');
var routes = require('./routes');
var titles = require('./routes/titles');
var issues = require('./routes/issues');
var issue = require('./routes/issue');
var sales = require('./routes/sales');
var http = require('http');
var path = require('path');
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.cookieParser());
app.use(express.session({secret: '1234567890QWERTY'}));
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(everyauth.middleware());
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/titles', titles.list);
app.get('/issues/:name/:year/:publisher', issues.list);
app.get('/issue/:name/:year/:publisher/:number/:variant/:print', issue.statistics);
app.get('/sales/:name/:year/:publisher/:number/:variant/:print/:certification/:grade', sales.list);
app.put('/sales', sales.update);
app.get('/recentsales', authorize(['admin']), sales.recentSales);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
这是我的everyauth.js,其中包含everyauth实现:
var everyauth = require('everyauth');
var databaseUrl = 'localhost:27017/comics';
var collections = ['users'];
var mongojs = require('mongojs');
var db = mongojs.connect(databaseUrl, collections);
var _ = require('lodash');
everyauth.debug = true;
var usersById = {};
var registrationFailedMsg = 'Registration failed.';
var loginFailedMsg = 'Login failed.';
everyauth.everymodule.findUserById(function (id, fn) {
if (usersById[id]) {
return fn(null, usersById[id]);
}
db.users.find({ $query: { _id: mongojs.ObjectId(id), isActive: true } }, function(err, user) {
if (err) {
return fn(new Error("Failed to retrieve user."), null);
}
if (user) {
user.id = user._id.toString();
usersById[id] = user;
console.log('Retrieved user: ' + user.firstName + ' ' + user.lastName);
return fn(null, user);
}
fn(new Error('Invalid user id.'), null);
});
});
everyauth.everymodule.logoutPath('/bye');
everyauth.everymodule.logoutRedirectPath('/');
everyauth.everymodule.handleLogout(function (req, res) {
req.logout();
this.redirect(res, this.logoutRedirectPath());
});
everyauth.password
.loginWith('email')
.getLoginPath('/login')
.postLoginPath('/login')
.loginView('login.jade')
.respondToLoginSucceed( function (res, user, data) {
if (user) {
this.redirect(res, (data.session.redirectTo || '/titles') )
}
})
.authenticate(function (login, password) {
var errors = [];
if (!login) {
errors.push('\r\n Missing login.');
}
if (!password) {
errors.push('\r\n Missing password.');
}
var promise = this.Promise();
if (errors.length) {
promise.fulfill(errors);
return promise;
}
db.users.find({ $query: { email: login, password: password, isActive: true } }, function(err, users) {
var user = users[0];
if (err) {
errors.push([loginFailedMsg]);
promise.fulfill(errors);
}
else {
if (user) {
user.id = user._id.toString();
usersById[user.id] = user;
promise.fulfill(user);
}
else {
console.log("\r\n User not found.");
errors.push([loginFailedMsg]);
promise.fulfill(errors);
}
}
});
return promise;
})
.getRegisterPath('/register')
.postRegisterPath('/register')
.registerView('register.jade')
.registerLocals(function (req, res, done) {
setTimeout(function () {
done(null, { title: 'Async Register' });
}, 200);
})
.extractExtraRegistrationParams(function (req) {
var loggedIn = null;
var loggedInUserRoles = null;
if (req.session.auth) {
if (req.session.auth.loggedIn) {
loggedIn = req.session.auth.loggedIn,
loggedInUserRoles = req.user.roles
}
}
return {
firstName: req.body.firstName,
lastName: req.body.lastName,
loggedIn: loggedIn,
loggedInUserRoles: loggedInUserRoles
};
})
.validateRegistration(function (newUserAttrs, errors) {
var promise = this.Promise();
db.users.find({ $query: { email: newUserAttrs.email } }, function(err, user) {
if (err) {
promise.fulfill([registrationFailedMsg]);
}
else {
// If the user exists, do not allow the user to register again.
if (user) {
promise.fulfill(['This email has already been registered']);
}
else {
promise.fulfill(null);
}
}
});
return promise;
})
.registerUser(function (newUserAttrs) {
var promise = this.Promise();
var userAttributes = {
email: newUserAttrs.email, password: newUserAttrs.password,
firstName: newUserAttrs.firstName, lastName: newUserAttrs.lastName, isValid: true,
roles: ['user']
};
db.users.save(userAttributes, function(err, user) {
if(err || !user) {
console.log("Failed to create user");
promise.fulfill([registrationFailedMsg]);
}
else {
if (user) {
console.log("Created user: " + JSON.stringify(user));
usersById[user._id.toString()] = user;
promise.fulfill(user);
}
else {
console.log("New user is null");
promise.fulfill([registrationFailedMsg]);
}
}
});
return promise;
})
.loginSuccessRedirect('../')
.registerSuccessRedirect('../');
module.exports = everyauth;
最后,这是我的authorize.js,我尝试获取req.user:
var _ = require('lodash');
var authorize = function (requiredRoles) {
return function (req, res, next) {
var sessionAuth = req.session.auth || {};
var loggedIn = sessionAuth.loggedIn;
req.session.redirectTo = req.originalUrl;
if (loggedIn) {
var userRoles = [];
if (_.isEmpty(req.user) || _.isEmpty(req.user.roles)) {
authorizationFailed(res);
return;
}
for (var i = 0; i < req.user.roles.length; i++) {
userRoles.push(req.user.roles[i].role.name);
}
if (userRoles && requiredRoles) {
if (_.intersection(userRoles, requiredRoles).length > 0) {
next();
return;
}
}
authorizationFailed(res);
return;
}
res.redirect(authorize.redirect || '/login');
}
};
function authorizationFailed(res) {
res.status(401); // 401 http status code = Unauthorized.
res.end('You are not authorized to view this resource');
}
module.exports = authorize;
注意:authorize.js开始发挥作用,我在app.js中有这一行:
app.get('/recentsales', authorize(['admin']), sales.recentSales);
提前感谢您的帮助。
答案 0 :(得分:1)
我最终弄明白是什么导致了这个问题。 app.js中的everyauth中间件必须放在路由器中间件之上,如下所示:
...
app.use(everyauth.middleware());
app.use(app.router);
...