5

J'utilise passport, express-session et connect-pg-simple.La session n'est pas correctement obtenue à partir d'un stockage, en utilisant express-session et passportjs

Le problème est que session n'est pas correctement obtenu à partir d'un stockage, où il obtient correctement (j'espère, mais doute) enregistré.

Mon installation est la même, comme dans de nombreux didacticiels, j'ai trouvé autour.

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

La partie intéressante est sortie de débogage de 'exprimer session', grâce à l'extraordinaire NPM-package debug.

Ainsi, lorsqu'une demande de /user/login vient, avec le nom d'utilisateur = Antonal, suivant arrive:

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 

Ainsi, la session est enregistrée dans db, nous allons le vérifier:

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) 

Jusqu'à présent, tellement bon.

Maintenant, je demande une page d'accueil d'un site Web et d'obtenir ce qui suit:

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 

Je vois, que « exprimer session » essaie de récupérer la session avec un autre SIDO6rS2cPlQ6JDaUUxxYRAg-VI5MmldaRE, qui fait t existe dans la base de données.

Pourquoi cela se produit-il?

AFAIK, il devrait chercher par SID = qiQfhyAvDDPD7muJLtGdZudKqMug0aAC ...

Quels problèmes peuvent être avec ma configuration?

Une clé secrète, « cookie-analyseur » n'est pas utilisé, selon recomentation « Remarque Depuis la version 1.5.0, le middleware cookie analyseur n'a plus besoin de » ...

Je suis complètement coincé avec cela.

S'il vous plaît, aidez.


Quelque chose ne va pas avec la génération sid

Quand je de session de modifier manuellement stockée sid pour le faire correspondre à ce que express-session est la demande,

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

séance est correctement et l'utilisateur récupéré est persisté:

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 

Donc, maintenant il est clair - sid paramètre est différent, lors de la génération de session et de l'extraire.

+0

Le comportement change-t-il si vous utilisez 'cookie-parser'? –

+0

@BrahmaDev, n ° – AntonAL

Répondre

0

Compris.

Dans le code client, j'utilisais fonction fetch avec le code suivant:

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

Cette approche m'a donné le problème en question.

Lorsque j'ai changé la méthode de demande pour 'GET' dans les routes et utilisé la redirection simple, tout ce que je l'ai eu à travailler.

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

Pourquoi cela se produit-il?

+0

Vous devez utiliser l'option 'credentials' dans fetch pour envoyer les cookies. https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch –

+0

inspectez les en-têtes dans les deux demandes envoyées par le client –