EveryAuth没有设置req.user

时间:2014-04-08 13:33:25

标签: javascript node.js express everyauth

我遇到的问题是没有设置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);

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我最终弄明白是什么导致了这个问题。 app.js中的everyauth中间件必须放在路由器中间件之上,如下所示:

...
app.use(everyauth.middleware());
app.use(app.router);
...