2012-06-25 16 views
17

Używam pssportjs z Expressem 2.x i przechowywania sesji. Po zalogowaniu uzyskuję polecenie req.User tylko raz. Jak tylko ponownie przekierowuję req.User jest niezdefiniowany.PassportJS: Jak uzyskać ponownie wpis.user w moich widokach

Oto mój config:

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')); 
}); 

To są moje trasy:

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 
      }); 
}); 

I wreszcie ten sposób próbuję uzyskać dostęp do obiektu użytkownika w moim zdaniem:

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

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

Po uwierzytelnieniu na Facebooku mój widok wyświetla poprawnie imię i nazwisko. Po kolejnym żądaniu strony, req.User jest undefiend (deserializacja nie jest wywoływana).

Co robię źle?

+2

Nicea pytanie. Bardzo pomogło :) –

+0

To głupie, że pomogło to bardziej niż "oficjalna" dokumentacja, deweloperzy powinni naprawdę poświęcić więcej czasu na wyjaśnianie swojej pracy. –

Odpowiedz

10

Użyj dynamicznych pomocników. Oto przykład z mojego w podstawowe user obiektu:

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 
     } 
    } 
}); 

Następnie z widokiem można po prostu użyć #{user.name} lub if user.isAdmin etc jako przedmiot user jest teraz dostępny w innych częściach aplikacji.

Możesz dodać go do pliku app.js lub wymagać z pliku zewnętrznego. Wszystkie moje dynamiczne pomocniki przechowuję pod /utils/helpers.js

2

Czy ustawiłeś oprogramowanie pośredniczące do paszportów? Z document, trzeba zrobić

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)); 
}); 

jeśli używasz Express, 3.x lub Połącz 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

Używam Express 2.x i skonfigurowałem go dokładnie tak (ale z magazynem sesji mongo). Zamierzam zaktualizować moje pytanie. Mam zaktualizować, aby wyrazić 3.x? – Sven

+0

Nie jestem pewien, która wersja jest lepsza. Myślę, że używanie najnowszej wersji jest interesujące i edukacyjne, ponieważ widzę, jak TJ poprawia implementację w czasie rzeczywistym. – smagch

2

Dobrze mam to:

Błąd I nie było w kodzie, który napisałem powyżej, co jest poprawne. Miałem zły sposób na łączenie z adresami URL, więc jakoś wymusiłem wyrażenie, aby utworzyć nową sesję za każdym razem, gdy użyłem jednego z niedziałających linków. Wraz z nową sesją straciłem również obiekt req.user.

Więc jeśli masz podobne problemy, sprawdź także swoje linki w swoim html.

Dziękuję wszystkim za pomoc.

+1

Czy możesz pogłębić swoją wiedzę o tym, jak mogę sprawdzić linki? –

0

Możesz przekazać informacje użytkownika do wyświetlenia w routerze:

res.render('user/dashboad', { 
    ... 
    user: req.session.passport.user, 
    ... 
Powiązane problemy