2013-03-26 29 views
5

Kullanıcı girişi ve oturumu oluşturmak için express ile redis kullanmaya çalışıyorum. Ben denediğimde bunu yaparkenNode.js/express - pasaportu redis ile kullanma, oturum yetkisiz hale getirme

curl -d 'email=testEmail&password=testPass' http://localhost:3000/users/session 

, pasaport serileştirme yoluyla çalışıyor ve daha sonra http 302. Ben, serileştirme sonra ne çözemedim verir ama: Bu bukle script kullanarak rotayı sınamak tarayıcımda curl yerine benim giriş html formumla, Bana "Yetkisiz" 401 gösterir ve konsol dosyalarımdan hiçbirini göremiyorum.

var express = require('express') 
    , fs = require('fs') 
    , cons = require('consolidate') 
    , http = require('http') 
    , flash = require('connect-flash') 
    , passport = require('passport') 
    , RedisStore = require("connect-redis")(express) //for sessions (instead of MemoryStore) 
    , redis = require('redis') 
    , env = process.env.NODE_ENV || 'development' 
    , config = require('./config/config')[env] 
    , db = redis.createClient(config.db.port, config.db.host); 

db.select(config.db.users) 
db.auth(config.db.auth); 

var app = express(); 

//require passport strategies (see code block below) 
require('./config/passport')(passport, config, app) 

app.use('/assets', express.static(__dirname + '/public')); 
app.use('/', express.static(__dirname + '/')); 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'html'); 

app.configure(function(){ 
    app.set('config', config); 
    app.set('db', db); 
    app.set('port', process.env.PORT || 3000); 
    app.engine('.html', cons.swig); 
    app.use(express.logger('dev')) 
    app.use(express.favicon(__dirname + '/public/img/favicon.ico')); 
    app.use(express.cookieParser()) 
    app.use(express.bodyParser()) //enables req.body 
    app.use(express.methodOverride()) //enables app.put and app.delete (can also just use app.post) 
    app.use(express.session({ 
     secret: 'topsecret', 
     cookie: {secure: true, maxAge:86400000}, 
     store: new RedisStore({ 
      client:db, 
      secret:config.db.auth 
     }) 
    })); 

    app.use(flash()) 
    app.use(passport.initialize()) 
    app.use(passport.session()) 
    app.use(app.router) 
}); 

// Bootstrap routes 
require('./config/routes')(app, passport); 

http.createServer(app).listen(app.get('port'), function(){ 
    console.log("Express server listening on port " + app.get('port')+', mode='+env); 
}); 

Ve seans POST rota: İşte benim app.js var ben sadece gerçekten MongoDB ile pasaport örneklerini bulabiliriz

app.post('/users/session', passport.authenticate('local', {successRedirect: '/', failureFlash: 'Invalid email or password.', successFlash: 'Welcome!'}), users.session); 

, bu yüzden aşağıda hakkında emin değilim. Bir kullanıcının bulmaya çalışır, ama geri aramaları hakkında emin değilim ya da ne pasaport yaptım dönüş kullanıcı bilgileri ile yapıyor:

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, 
    function(email, password, done) { 

     var db = app.get('db') 
     var multi = db.multi(); 

     db.get('email:'+email, function(err, uid){ 
      if (err) { console.log(err); return err } 
      if (!uid) { console.log('no uid found'); return null } 

      console.log('found '+uid) 
      db.hgetall('uid:'+uid, function(err, user){ 
       if (err) { console.log(err); return err } 
       if (!user) { 
        console.log('unkwn usr') 
        return done(null, false, { message: 'Unknown user' }) 
       } 

       if (password != user.password) { 
        console.log('invalid pwd') 
        return done(null, false, { message: 'Invalid password' }) 
       } 
       console.log('found user '+user) //I see this fine with curl, but no logs with browser 
       return done(null, user) 
      }); 
     });  
    } 
)) 

Pasaport seri:

passport.serializeUser(function(user, done) { 
    console.log('passport serializing...'+user.name) 
    done(null, user.name) //no idea what happens to it after this. returns a 302 with curl, and 401 with browser 
}) 

Neden bunu yapar Bir tarayıcıda farklı bir şekilde kıvırmaktan daha mı etkilidir? Herhangi bir yardım veya yorum çok takdir!

+0

Fark, tarayıcınızın bir (soldaki) oturum çerezi gönderebiliyor olmasıdır. Tarayıcınızı Gizli/Özel modda çalıştırmayı deneyin. Ayrıca, 'passport.deserializeUser' uyguluyor musunuz? Değilse, yapmalısın. – robertklep

+0

Gizli modda ve önbellek/çerezleri sildi, aynı sonuçları. Henüz deserializeUser'e ihtiyacım olan noktaya gelmedim, bu seansı kaldırmak için doğru olduğuna inanıyorum? Bir tarayıcı kullandığımda hala "Yetkisiz" gösteriliyor ve konsol.log'larım hiçbiri gösterilmiyor. –

cevap

1

Figured out out! veri tabanına sahip pasaport kullanmak için (sadece Mongo değil), önce bir kukla kullanıcı ile denemenizi tavsiye ederim. İşte yaptığım şey.

Giriş Formu (login.html):

<form method="post" action="http://localhost:3000/users/session" name="loginform"> 
    <input id="login_input_username" type="text" name="email" /> 
    <input id="login_input_password" type="password" name="password" autocomplete="off" /> 
    <input type="submit" name="login" value="Submit" /> 
</form> 

Yönlendirme (route.js):

app.post('/users/session', passport.authenticate('local'), 
    function(req, res){ 
     res.end('success!'); 
    }); 

Pasaport Yerel Stratejisi kurulumu (passport.js):

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, 
    function(email, password, done) { 
     //find user in database here 
     var user = {id: 1, email:'test', password:'pass'}; 
     return done(null, user); 
    } 
)); 

passport.serializeUser(function(user, done) { 
    //serialize by user id 
    done(null, user.id) 
}); 

passport.deserializeUser(function(id, done) { 
    //find user in database again 
    var user = {id: 1, email:'test', password:'pass'}; 
    done(null, user); 
}) 

Veritabanımda iki kez kullanıcı bulmamın gerekip gerekmediğini ya da hatalı bir şekilde seriyi hatalı kullanıyorum.

+6

'serializeUser''ün amacı, oturumdaki kullanıcı için bazı tanımlayıcı bilgileri depolamaktır; 'deserializeUser', bu bilgileri kullanarak tam kullanıcı bilgilerini tekrar alır. Tüm kullanıcı nesnesini oturumda saklayabilir (böylece veritabanını yeniden sorgulamanız gerekmez) ya da bir kimliği saklayabilirsiniz (bu durumda, kimliği çözmek için "deserializeUser" veritabanını sorgulamanız gerekir) kullanıcı kaydına). Kullanıcı nesnesinin olduğu gibi oturumda depolanabiliyor olmasına bağlı olarak değişir. – robertklep

+1

(Ayrıca, tüm kullanıcı nesnesini saklarsanız, veritabanındaki kullanıcı bilgisinden, kullanıcının verilerinin son oturumu seri hale getirilmesinden bu yana değiştiyse, kullanıcı veritabanından farklı olabilir) – robertklep

+0

Hmm -serializing ve kullanıcı bir şey değiştirdi (profil isimlerini söyle), daha sonra serileştirilmiş çerez versiyonu db'de ne eşleşmeyecek. Yani bu oturumun geçersiz olacağını (ikinci yaklaşımda) değil mi?ve desutize etmek için db'yi sorgulamaktan kaçınmak istemeyiz mi? –

İlgili konular