2012-06-25 3 views
17

Я использую pssportjs с express 2.x и хранилищем сессий. После входа я получаю req.User только один раз. Как только я снова перенаправляю req.User не определен.PassportJS: Как получить req.user в моих представлениях

Вот мой конфиг:

passport.serializeUser(function(user, done) { 
    done(null, user._id); 
}); 

passport.deserializeUser(function(userId, done) { 
    User.findOne({_id: userId} ,function(err, user){ 
    done(err, user); 
    }); 
}); 

// Authentication Strategy 
passport.use(new FacebookStrategy({ 
    clientID: CONFIG.fb.appId, 
    clientSecret: CONFIG.fb.appSecret, 
    callbackURL: CONFIG.fb.callbackURL 
    }, 
    function(accessToken, refreshToken, profile, done) { 
    // asynchronous verification, for effect... 
    process.nextTick(function() { 

     User.findOne({ 'accounts.uid': profile.id, 'accounts.provider': 'facebook' }, function(err, olduser) { 

      if(olduser) { 
      done(null, olduser); 
      } else { 
      var newuser  = new User(); 
      var account  = {provider: "facebook", uid: profile.id}; 
      newuser.accounts.push(account); 
      newuser.firstname = profile.name.givenName; 
      newuser.lastname = profile.name.familyName; 
      newuser.email  = "TBD..."; 

      newuser.save(function(err) { 
       if(err) { throw err; } 
       done(null, newuser); 
      }); 
      } 
     }); 
    }); 
    } 
)); 

var app = module.exports = express.createServer(); 

// configure express 
app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'ejs'); 
    app.use(express.compiler({ src : __dirname + '/public', enable: ['less']})); 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 

    //app.use(express.session({ secret: "keyboard cat" })); 
    app.use(express.session({ 
    secret: "victory cat", 
    store: new MongoStore({ 
     url: CONFIG.dbMongo.url 
     }) 
    })); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

Это мои маршруты:

app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['user_status', 'user_photos'] })); 

app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/index', failureRedirect: '/' })); 

app.get('/index', function(req, res) { 

      res.render('index.ejs', { 
       siteTitle: "Welcome", 
       siteUrl: CONFIG.server.siteUrl, 
       user: req.user 
      }); 
}); 

И, наконец, это, как я пытаюсь получить доступ к объекту пользователя на мой взгляд:

<div class="page-header"> 
    <h3><%= siteTitle %></h3> 
</div> 

<% if (!user) { %> 
    <p>Not logged in !</p> 
<% } else { %> 
    <p>Hello, <%= user.firstname %> <%= user.lastname %>.</p> 
<% } %> 

После аутентификации с помощью facebook мой вид отображает имя и фамилию правильно. После другого запроса страницы req.User является undefiend (десериализация не вызывается).

Что я делаю неправильно?

+2

Хороший вопрос. Это помогло много :) –

+0

Глупо, что это помогло больше, чем «официальная» документация, разработчикам действительно нужно больше времени, чтобы объяснить свою работу. –

ответ

10

Использование динамических помощников. Вот пример моего усеченного user объекта:

app.dynamicHelpers({ 
    user: function(req, res){ 
     var roles, name; 

     if (req.session && req.session.auth == true) { 
      roles = ['member']; 
      name = (req.session.user) ? req.session.user.name : 'Registered member'; 
      id = (req.session.user) ? req.session.user.id : 0; 
     } 
     else { 
      roles = ['guest']; 
      name = 'Guest'; 
      id = null; 
     } 

     return { 
      name: name, 
      id: id, 
      roles: roles, 
      isGuest: roles.indexOf('guest') !== -1, 
      isAdmin: roles.indexOf('admin') !== -1 
     } 
    } 
}); 

Тогда из видов, которые вы можете просто использовать #{user.name} или if user.isAdmin и т.д., как объект user теперь доступен для других частей приложения.

Вы можете добавить его в app.js или потребовать от внешнего файла. Я сохраняю все мои динамические помощники в /utils/helpers.js

2

Вы установили паспортное ПО? Из document, что вам нужно сделать

app.configure(function() { 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.session({ secret: 'keyboard cat' })); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(YOUR_STATIC_DIR_PATH)); 
}); 

если вы используете Экспресс 3.x или Connect 2.x, set cookie secret instead of session secret

app.configure(function() { 
    app.use(express.cookieParser('keyboard cat')); 
    app.use(express.session()); 
    app.use(express.bodyParser()); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(YOUR_STATIC_DIR_PATH)); 
}); 
+0

Я использую express 2.x, и я настроил его точно так же (но с хранилищем сеансов mongo). Я собираюсь обновить свой вопрос. Должен ли я обновить, чтобы выразить 3.x? – Sven

+0

Я не уверен, какая версия лучше. Я думаю, что использование последней версии является интересным и образовательным, так как я вижу, как TJ улучшают реализацию в реальном времени. – smagch

2

Все права я получил его:

Ошибку я не было в коде, который я написал выше, что правильно. У меня был неправильный способ привязки к URL-адресам, поэтому я как-то принуждал выразить создание нового сеанса каждый раз, когда я использовал одну из неработающих ссылок. С новым сеансом я также потерял объект req.user.

Так что если у вас похожие проблемы, проверьте свои ссылки внутри своего html.

Спасибо всем за помощь.

+1

Можете ли вы глубже узнать, как я могу проверить мои ссылки? –

0

Вы можете передать данные пользователя для просмотра в маршрутизаторе:

res.render('user/dashboad', { 
    ... 
    user: req.session.passport.user, 
    ... 
Смежные вопросы