2017-08-31 42 views
5

का उपयोग कर सत्र से सही ढंग से प्राप्त नहीं किया गया है, मैं passport, express-session और connect-pg-simple का उपयोग कर रहा हूं।एक्सप्रेस-सत्र और पासपोर्टजे

समस्या यह है कि सत्र भंडारण से सही ढंग से प्राप्त नहीं किया गया है, जहां यह ठीक से हो जाता है (मुझे उम्मीद है, लेकिन संदेह) बचाया गया है।

मेरा सेटअप वही है, जैसा कि कई ट्यूटोरियल में, मैंने पाया है।

server.js:

import express from 'express'; 
import next from 'next'; 
import bodyParser from 'body-parser'; 
import session from 'express-session'; 
import connectPgSimple from 'connect-pg-simple'; 
const sessionStorage = connectPgSimple(session); 
import initAuthentication from '!/server/authentication'; 

const dev = process.env.NODE_ENV !== 'production'; // eslint-disable-line 
const port = process.env.PORT || 3000; // eslint-disable-line 
const app = next({ dev }); 

app.prepare() 
.then(() => { 
    const server = express(); 

    server.use(express.static('public')); 

    /* Note Since version 1.5.0, the cookie-parser middleware no longer needs 
    to be used for this module to work. This module now directly reads and writes 
    cookies on req/res. Using cookie-parser may result in issues 
    if the secret is not the same between this module and cookie-parser. 
    https://www.npmjs.com/package/express-session */ 
    // server.use(cookieParser()); 

    server.use(bodyParser.json()); // for parsing application/json 
    server.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded 
    server.use(session({ 
    secret: 'keyboard cat', 
    store: new sessionStorage(), 
    resave: false, 
    saveUninitialized: false, 
    cookie: { 
     secure: false, 
     maxAge: 30 * 24 * 60 * 60 * 1000 
    }}) 
); 

    initAuthentication(server); 
}); 

authentication.js:

import passport from 'passport'; 
import LocalStrategy from 'passport-local'; 
import bcrypt from 'bcrypt'; 
import {User} from '!/server/db'; 
import util from 'util'; 

User.prototype.validPassword = function(password) { 
    return bcrypt.compareSync(password, this.passwordHash); 
}; 

User.authenticate = (username, password, done) => { 
    User.findOne({where: {nickname: username}}).then(user => { 
    if (!user) { 
     return done(null, false, { message: 'Неверное имя пользователя.' }); 
    } 
    if (!user.validPassword(password)) { 
     return done(null, false, { message: 'Неверный пароль.' }); 
    } 
    return done(null, user); 
    }).catch(err => { 
    return done(err); 
    }); 
}; 

export default function initAuthentication(server) { 
    server.use(passport.initialize()); 
    server.use(passport.session()); 

    passport.use('local-signIn', new LocalStrategy(User.authenticate)); 

    passport.serializeUser((user, done) => { 
    console.log('> serializeUser "'+user.nickname+'" ('+user.id+')'); 
    done(null, user.id); 
    }); 
    passport.deserializeUser((id, done) => { 
    console.log('> deserializeUser with id: ' + id) 
    User.findById(id).then(user => { 
     done(null, user); 
    }).catch(error => { 
     console.log('Error in passport.deserializeUser: ' + error); 
     done(error, null); 
    }); 
    }); 

    server.post('/user/login', 
    passport.authenticate('local-signIn'), 
    (req, res) => { 
     // If this function gets called, authentication was successful. 
     // `req.user` contains the authenticated user. 
     console.log('Authenticated user "'+req.user.nickname+'"'); 
     req.login(req.user, (err)=> { 
     if (err) console.log(err); 
     console.log('\t Session established for user "'+req.user.nickname+'"'); 
     res.json(req.user); 
     }); 
    } 
); 

    function logAuthenticationStatus(req, res, next) { 
    console.log('Authentication status:') 
    console.log('\treq.cookies: ' + util.inspect(req.cookies)); 
    console.log('\treq.isAuthenticated: ', req.isAuthenticated()); 
    console.log('\treq.session: ', req.session); 
    if (req.user) { 
     console.log('\tLogged in as "'+req.user.nickname+'"'); 
    } else { 
     console.log('\tNot logged in'); 
    } 
    next(); 
    } 

    server.use(logAuthenticationStatus); 

    server.get('/logout', function(req, res){ 
    req.logout(); 
    res.redirect('/'); 
    }); 
} 

दिलचस्प भाग की डिबग आउटपुट है, 'व्यक्त सत्र' अद्भुत NPM-पैकेज debug के लिए धन्यवाद।

तो, जब /user/login के लिए एक अनुरोध आता है, उपयोगकर्ता नाम के साथ = AntonAL, निम्न होता है:

Executing (default): SELECT "id", "nickname", "email", "password", "passwordHash", "lastLoggedIn", "createdAt", "updatedAt" FROM "users" AS "user" WHERE "user"."nickname" = 'AntonAL' LIMIT 1; 
> serializeUser "AntonAL" (1) 
Authenticated user "AntonAL" 
> serializeUser "AntonAL" (1) 
    Session established for user "AntonAL" 
    express-session saving qiQfhyAvDDPD7muJLtGdZudKqMug0aAC +23ms 
    express-session split response +0ms 
    express-session set-cookie connect.sid=s%3AqiQfhyAvDDPD7muJLtGdZudKqMug0aAC.0wIcunkcEjhaUzs4H7w4uuv6u%2FBKXMROuAm6%2FG0vVQw; Path=/; Expires=Sat, 30 Sep 2017 10:55:31 GMT; HttpOnly +1ms 
info: POST /user/login 200 50ms statusCode=200, url=/user/login, host=localhost:3000, content-type=application/json, origin=http://localhost:3000, accept-encoding=gzip, deflate, connection=keep-alive, accept=application/json, user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8, referer=http://localhost:3000/user/login, content-length=44, accept-language=ru, method=POST, httpVersion=1.1, originalUrl=/user/login, , responseTime=50, user=AntonAL 

तो, सत्र DB में सहेजा जाता है, यह जाँच करें: अब तक

SELECT * FROM session WHERE sid='qiQfhyAvDDPD7muJLtGdZudKqMug0aAC';` 

sid    |                  sess                  |  expire   
----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------- 
qiQfhyAvDDPD7muJLtGdZudKqMug0aAC | {"cookie":{"originalMaxAge":2592000000,"expires":"2017-09-30T10:55:31.514Z","secure":false,"httpOnly":true,"path":"/"},"passport":{"user":1}} | 2017-09-30 13:55:32 
(1 row) 

, बहुत अच्छा।

अब, मैं एक वेबसाइट के मुख पृष्ठ का अनुरोध कर रहा हूँ और हो रही है:

info: GET/200 486ms statusCode=200, url=/, host=localhost:3000, accept-encoding=gzip, deflate, cookie=connect.sid=s%3AO6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE.M4iFzpVZP9fNa%2FLEomsMD8D9LjA1uFnDMnXT%2FHR3wyk; meteor_login_token=4YvVuK0V4adQJaMM2setEAx9_Ki7q6At19YfAvwyOJ8; _ga=GA1.1.1413606909.1501852025, connection=keep-alive, upgrade-insecure-requests=1, accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8, referer=http://localhost:3000/user/login, cache-control=max-age=0, accept-language=ru, method=GET, httpVersion=1.1, originalUrl=/, , responseTime=486, user=null 
    express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +516ms 
    express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +1ms 
    express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +4ms 
    express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +1ms 
    express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +1ms 
    express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +0ms 
    express-session no session found +1ms 
Authentication status: 
    req.cookies: undefined 
    req.isAuthenticated: false 
    req.session: Session { 
    cookie: 
     { path: '/', 
     _expires: 2017-09-30T11:15:52.123Z, 
     originalMaxAge: 2592000000, 
     httpOnly: true, 
     secure: false } } 
    Not logged in 
    express-session no session found +7ms 

मैं देख रहा हूँ, कि 'व्यक्त सत्र' एक और सिडO6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE, करता है 'के साथ सत्र लाने की कोशिश करता है डेटाबेस में मौजूद नहीं है।

ऐसा क्यों होता है?

AFAIK, यह सिड = qiQfhyAvDDPD7muJLtGdZudKqMug0aAC द्वारा प्राप्त किया जाना चाहिए ...

क्या मुद्दों मेरी सेटअप के साथ हो सकता है?

एक गुप्त कुंजी, 'कुकी-पार्सर' recomentation के अनुसार नहीं किया जाता है, 'नोट संस्करण 1.5.0 के बाद से, कुकी-पार्सर मिडलवेयर नहीं रह गया है की जरूरत है' ...

मैं पूरी तरह से इस के साथ फंस कर रहा हूँ।

कृपया, सहायता करें।


कुछ sid पीढ़ी के साथ गलत है

जब मैं मैन्युअल रूप से बदल संग्रहीत सत्र के sid यह क्या express-session अनुरोध कर रहा है करने के लिए मिलान करने के लिए,

UPDATE session SET sid='O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE' WHERE sid='qiQfhyAvDDPD7muJLtGdZudKqMug0aAC'; 

सत्र सही ढंग से लाई गई है और उपयोगकर्ता है जारी:

express-session fetching O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +3s 
    express-session session found +2ms 
> deserializeUser with id: 1 
Executing (default): SELECT "id", "nickname", "email", "password", "passwordHash", "lastLoggedIn", "createdAt", "updatedAt" FROM "users" AS "user" WHERE "user"."id" = 1; 
Authentication status: 
    req.cookies: undefined 
    req.isAuthenticated: true 
    req.session: Session { 
    cookie: 
    { path: '/', 
    _expires: 2017-09-30T10:55:31.514Z, 
    originalMaxAge: 2592000000, 
    httpOnly: true, 
    secure: false }, 
    passport: { user: 1 } } 
    Logged in as "AntonAL" 
    express-session saving O6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE +577ms 
    express-session split response +1ms 
info: GET/200 585ms statusCode=200, url=/, host=localhost:3000, accept-encoding=gzip, deflate, cookie=connect.sid=s%3AO6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE.M4iFzpVZP9fNa%2FLEomsMD8D9LjA1uFnDMnXT%2FHR3wyk; meteor_login_token=4YvVuK0V4adQJaMM2setEAx9_Ki7q6At19YfAvwyOJ8; _ga=GA1.1.1413606909.1501852025, connection=keep-alive, upgrade-insecure-requests=1, accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8, referer=http://localhost:3000/user/login, cache-control=max-age=0, accept-language=ru, method=GET, httpVersion=1.1, originalUrl=/, , responseTime=585, user=AntonAL 

तो, अब यह स्पष्ट है - सत्र उत्पन्न करते समय और लाने के दौरान सिड पैरामीटर अलग है।

+0

यदि आप 'कुकी-पार्सर' का उपयोग करते हैं तो क्या व्यवहार बदलता है? –

+0

@ ब्रह्माडेव, संख्या – AntonAL

उत्तर

0

यह पता लगाया।

ग्राहक कोड में, मैं निम्नलिखित कोड के साथ fetch फ़ंक्शन का उपयोग किया गया था:

fetch('/user/login', { 
    method: 'POST', 
    headers: { 
    'Content-Type': 'application/json', 
    }, 
    body: JSON.stringify(values) 
}); 

यह दृष्टिकोण मुझे प्रश्न में समस्या दे दी है।

जब मैंने मार्गों में 'GET' करने के लिए अनुरोध विधि बदल दी और सादे रीडायरेक्ट का उपयोग किया, तो मुझे यह सब कुछ काम करने के लिए मिला।

window.location.href = "/login?"+querystring.stringify(values); 

ऐसा क्यों होता है?

+0

आपको कुकीज़ भेजने के लिए लाने में 'प्रमाण-पत्र' विकल्प का उपयोग करने की आवश्यकता है। https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch –

+0

क्लाइंट से भेजे गए दोनों अनुरोधों में हेडर का निरीक्षण करें –

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