В приложении node.js как можно асинхронно достичь эффекта контроллера rails before_filter? - PullRequest
2 голосов
/ 22 октября 2010

У меня есть приложение node.js Express с базовой системой аутентификации пользователей, в которой сеанс хранится в Redis.Я хотел бы написать и повторно использовать функцию current_user (), которая заполняет JSON-представление зарегистрированного пользователя (если он есть) в переменной current_user.Вот код для извлечения пользователя:

if( req.cookie('fingerprint') ) {
  redis_client.get("users:fingerprint:"+req.cookie("fingerprint"), function(err,id) {
    redis_client.get("users:id:"+id, function(err,user) {
      current_user = JSON.parse(user);
    })
  })
}

, если бы я хотел использовать это только один раз, я мог бы поставить вызов res.render после этой строки current_user, но я бы хотел заполнитьПеременная current_user для всех контроллеров и действий.

Я новичок в узле, поэтому, возможно, здесь есть фундаментальная концепция, которую мне не хватает ... но в принципе мне нужен способ вернуть переменную current_user сверхусинхронный контекст или достичь того же эффекта асинхронно.Например,

app.get('/', function(req,res) {
  current_user = current_user();
  res.render('home', {layout: "layout.ejs", locals: {current_user: current_user}})
})

Спасибо.

Ответы [ 2 ]

4 голосов
/ 22 октября 2010

Экспресс-маршруты принимают третий аргумент: next, это позволяет передавать управление на следующий соответствующий маршрут. Вы можете использовать это для создания до фильтров на основе маршрутов, например:

app.get('/admin', function(req, res, next){
  if(authenticated_user()) {
    req.user = get_user();
    next(); 
  }
  else // prompt for login
});

app.get('/admin/:id', function(req, res){
  // foo
}

Надеюсь, это поможет, для получения дополнительной информации см. Прохождение управления маршрутом в официальном экспресс-руководстве

обновление

СУХОЙ способ добиться того же, используя о-о-круто Промежуточное программное обеспечение маршрута

function checkAuthentication(req, res, next){
  if(authenticated_user()) {
    req.user = get_user();
    next(); 
  }
  else // prompt for login
}

app.get('/admin/:id', checkAuthentication, function(req, res){
  // foo
});
1 голос
/ 26 октября 2010

Почему бы вам просто не использовать dynamicHelpers?

во-первых, сохранить текущего пользователя в сеансе.Так как вы используете redis, проверьте что-то вроде connect-redis для экспресса.Затем сохраните его в сеансе следующим образом:

if( req.cookie('fingerprint') ) {
  redis_client.get("users:fingerprint:"+req.cookie("fingerprint"), function(err,id) {
    redis_client.get("users:id:"+id, function(err,user) {
      req.session.user = JSON.parse(user);
    })
  })
}

Сделайте его доступным как dynamicHelper:

app.dynamicHelpers({
   current_user: function(req) {
        return req.session.user;
   }
});

Теперь current_user доступен для всех ваших обработчиков маршрутов и представлений!

app.get('/admin/:id', function(req, res){
  if(current_user) {
     //do what you want here...
  }
});

при входе в систему, просто сгенерируйте сеанс следующим образом:

req.session.regenerate(function() {
      // same as above!
  req.session.user = JSON.parse(user);
});

при выходе из системы, уничтожьте сеанс:

req.session.destroy(function() {
  res.redirect('/');
});
...