2013-02-22 27 views
15

मैं अपने ऐप में प्रमाणीकरण के लिए पासपोर्ट का उपयोग कर रहा हूं, और मैं एक्सप्रेस का भी उपयोग कर रहा हूं। मेरी समस्या को संक्षेप में प्रस्तुत करने के लिए: अपना लॉगिन कार्यक्षमता शुरू में ठीक काम करता है, लेकिन के बाद किसी भी उपयोगकर्ता के सत्र का समय समाप्त, कोई उपयोगकर्ताओं में लॉग इन कर रहा प्रमाणीकरण के लिए मानक स्थानीय रणनीति का उपयोग कर रहा हैंनोड.जेएस एक्सप्रेस पासपोर्ट कुकी समाप्ति

।।

मैं अपने सेटअप के आधार पर संभव के रूप में एक उदाहरण के रूप में नंगा शामिल करेंगे:

//------------- 
//Set up authentication with Passport 
//------------- 
var userModel = require('./models/user')(db); 
passport.use(new LocalStrategy(
    function(username, password, done) { 
     var errorMessage = 'Incorrect username/password combination.'; 
     userModel.GetUserByUsername(username, function(err, user) { 
      if (err) { return done(err); } 
      if (!user) { 
       return done(null, false, { message: errorMessage }); 
      } 

      user.validatePassword(password, function(isPasswordCorrect) { 
       if (!isPasswordCorrect) 
       { 
        return done(null, false, { message: errorMessage }); 
       } 

       //Update with login date 
       userModel.UpdateUserWithLogin(username, user.currentLoginTime, function(err){ 
        //if we have an error here, we should probably just log it 
        if(err) 
        { 
         console.log(err); 
        } 
       }); 

       return done(null, user); 
      }); 
     }); 
    } 
)); 

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

passport.deserializeUser(function(user, done) { 
    userModel.GetUserByUsername(user._id, function(err, user) { 
      done(err, user); 
     }); 
}); 

//------------- 
//Set up express and configure 
//------------- 
var sessionStore = new SkinStore(db); 
var app = express(); 

app.configure(function(){ 
    app.set('port', process.env.PORT || 3000); 
    app.set('views', __dirname + '/views'); 
    app.engine('html', consolidate.swig); 
    app.set('view engine', 'html'); 
    swig.init({ 
     root: '.', 
     allowErrors: true, // allows errors to be thrown and caught by express instead of suppressed 
     autoescape: false}); 

    app.use(express.logger('dev')); 

    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieParser("[mysecrethere]")); 
    app.use(express.session({ store: sessionStore, 
          cookie: { expires : new Date(Date.now() + 3600000) } //1 Hour 
          })); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(flash()); 
    app.use(expressValidator); 

    app.use(express.static(path.join(__dirname, 'public'))); 

    //Dynamic helpers 
    app.use(require('./helpers/DynamicHelpers')); 

    app.use(app.router); 
}); 

app.get('/login', routes.login); 
app.post('/login', passport.authenticate('local', {failureRedirect: '/login', 
               badRequestMessage: "Please enter username and password", 
               failureFlash: true }), 
               function(req, res) { 
                var targetUrl = req.session.pageAfterLogin; 
                delete req.session.pageAfterLogin; 
                res.redirect(targetUrl || '/account'); 
               }); 

app.get('/account', IsAuthenticated, routes.account.show); 

और IsAuthenticated सहायक समारोह:

function IsAuthenticated(req,res,next){ 
    if(req.isAuthenticated()) 
    { 
     next(); 
    } 
    else 
    { 
     //save the requested page and then redirected 
     req.session.pageAfterLogin = req.url; 
     req.flash("error", "You must be logged in first!"); 
     res.redirect('/login'); 
    } 
} 

क्या मैं डिबगिंग करके प्राप्त कर सकते है कि, सफल होने के बाद प्रमाणीकरण (और एक कुकी समाप्त होने के बाद), मैंने इस तर्क को (ऊपर से) मारा:

function(req, res) { 
    var targetUrl = req.session.pageAfterLogin; 
    delete req.session.pageAfterLogin; 
    res.redirect(targetUrl || '/account'); 
} 

जहां मैं देख सकता हूं कि "req" सत्र सही तरीके से सेट किया गया है, पासपोर्ट जानकारी ठीक से संग्रहीत है। फिर, रीडायरेक्ट होता है, नया अनुरोध में कोई सत्र जानकारी संग्रहीत नहीं है, और इसकी पूरी तरह से नया सत्र आईडी है। मुझे संदेह था कि क्लाइंट पर कोई कुकी सेट नहीं की जा रही थी, और यह मामला प्रतीत होता है, जो लगातार सत्रों की कमी को समझाना चाहिए।

हालांकि, मुझे पता नहीं लगा सकता है क्यों कोई नई कुकी सेट नहीं की जा रही है। क्या ऐप कॉन्फ़िगर किया गया है इसके साथ कुछ गड़बड़ है जो इंगित करेगी कि यह क्यों हो रहा है?

मुझे यह जोड़ना चाहिए कि नोड.जेएस इंस्टेंस को पुनरारंभ करने से समस्या ठीक हो जाती है, यह ऐसा कुछ नहीं है जो उत्पादन में सहनशील होगा।

धन्यवाद।

अद्यतन: मैं यह देखने के लिए कि क्या HTTP/एस यातायात के साथ हो रहा था फ़िडलर भाग गया, और मैं देख सकते हैं कि जब यह शुरू में काम करता है, मैं ब्राउज़र (मैं कई की कोशिश की) जो तब है में एक कुकी सेट हो रही है बाद के अनुरोधों पर सर्वर पर वापस भेज दिया।

जब यह काम नहीं करता है, ब्राउज़र सर्वर पर कुकीज़ नहीं भेज रहा है, और इसलिए नोड एक सेट-कुकी शीर्षलेख भेज रहा है जो प्रत्येक बार एक नई कुकी प्रदान करता है। अब तक मुझे इसका कारण निर्धारित करने में कोई भाग्य नहीं है।

+0

आपको लगता है कि passport.deserializeUser चलाया जाता है, कि user._id मौजूद है और अपने मॉडल उपयोगकर्ता पता चलता है कि जांच की है? इसके अलावा serializeUser को एक आईडी को कॉलबैक करना चाहिए, उपयोगकर्ता ऑब्जेक्ट नहीं। –

+0

मैं इसका परीक्षण करने में सक्षम था (अंत में), और मैं देख सकता हूं कि serializeUser ** ** ** कॉल हो रहा है। हालांकि, बाद के रीडायरेक्ट में, deserializeUser चल रहा नहीं है। SerializeUser में, उपयोगकर्ता ठीक से पाया गया था, यह अभी भी जारी नहीं लग रहा है। और मैं उपयोगकर्ता के बजाय user._id को क्रमबद्ध करने के लिए काम करूंगा। मैंने मूल रूप से ऐसा किया था लेकिन कुछ कारणों से स्विच किया था जब से मैं भूल गया था। – creativename

उत्तर

24

मैंने इसे समझ लिया, हालांकि मुझे जवाब पसंद नहीं है।

टीएल; डॉ; - समाप्त होने की बजाय maxAge का उपयोग करें।


यह मुद्दा प्रत्येक कुकी (जिसे स्वचालित रूप से एक्सप्रेस द्वारा सेट किया गया है) पर समाप्त होने वाली समाप्ति तिथि में रूट किया गया था। मैंने देखा कि सेट की गई प्रत्येक कुकी की एक ही समाप्ति तिथि थी, जो अंततः अतीत में समाप्त हो गई और इसलिए तुरंत समाप्त हो गई।

कि के कारण यहाँ था:

cookie: { expires : new Date(Date.now() + 3600000) } 

नई तिथि केवल एक बार सर्वर प्रारंभ पर बनाया जा रहा था,। यह समाप्ति तिथि हर बार एक जैसी होने का कारण बन रहा था।मूल पोस्ट में कोड के आधार पर, मैं यह नहीं समझ सकता कि यह क्यों काम नहीं करता है और फिर भी मुझे जो ऑनलाइन उदाहरण मिला है वह सटीक कोड का उपयोग करता है। मैंने इस दिनांक को बनाए गए फ़ंक्शन को परिभाषित करके सत्यापित किया है, और जांच कर रहा है कि इसे केवल सर्वर प्रारंभ पर ही बुलाया गया है।

इस समस्या को हल करने के लिए, मैं "समाप्ति" के बजाय maxAge को परिभाषित कर रहा हूं। maxAge एक तिथि के बजाय कई मिलीसेकंड लेता है, और ऐसा लगता है कि यह सभी कुकीज़ पर समाप्ति तिथि सही ढंग से सेट कर रहा है।

मुझे यह सुनना अच्छा लगेगा कि कोई यह समझा सकता है कि यह पहली जगह क्यों हो रहा है, क्योंकि अन्य इसे सफलतापूर्वक उपयोग करते हैं। कोई विचार?

मूल्य है, जो एक स्ट्रिंग या वस्तु JSON करने के लिए परिवर्तित किया जा सकता है, जहां के लिए नीचे

app.configure(function(){ 
    app.set('port', process.env.PORT || 3000); 
    app.set('views', __dirname + '/views'); 
    app.engine('html', consolidate.swig); 
    app.set('view engine', 'html'); 
    swig.init({ 
     root: '.', 
     allowErrors: true, // allows errors to be thrown and caught by express instead of suppressed 
     autoescape: false}); 

    app.use(express.logger('dev')); 

    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieParser("[mysecrethere]")); 
    app.use(express.session({ store: sessionStore, 
          cookie: { maxAge : 3600000 } //1 Hour 
          })); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(flash()); 
    app.use(expressValidator); 

    app.use(express.static(path.join(__dirname, 'public'))); 

    //Dynamic helpers 
    app.use(require('./helpers/DynamicHelpers')); 

    app.use(app.router); 
}); 
+2

धन्यवाद @creativename। मैं इस समस्या के साथ दिनों से संघर्ष कर रहा हूं। यह पता लगाने के बाद कि पासपोर्ट ने समाप्त होने वाली संपत्ति को अपडेट नहीं किया था, मैंने सोचा कि यह असंभव होगा। लेकिन आपका समाधान एक आकर्षण की तरह काम करता है! –

+1

धन्यवाद..यह देखना मुश्किल है। अब समझ में आता है। – Timmerz

+1

मेरा मानना ​​है कि मैं इस मुद्दे में भी भाग रहा हूं, जो उपयोगकर्ताओं के प्रभाव को दुनिया के दूसरी तरफ एक टाइमज़ोन में प्रभावित करता है। –

-2

सेट कुकी नाम मेरे कार्य कोड देखें। पथ विकल्प "/" पर डिफ़ॉल्ट है।

res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });

maxAge विकल्प सेट करने के लिए एक सुविधा विकल्प है मिलीसेकेंड में वर्तमान समय के सापेक्ष "समाप्त हो रहा है"। निम्नलिखित पिछले उदाहरण के बराबर है।

res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })

इसके अलावा लिंक

http://expressjs.com/api.html#res.cookie

संबंधित मुद्दे