2017-07-29 3 views
1

Ich benutze Sails.js und versuche, eine einfache Anmeldung mit dem Speichern der Benutzerinformationen in die Sitzung zu tun. Hier ist mein Code für die Login-Aktion:Sails.js Sitzung nicht auf erste Anfrage gespeichert

AuthService.login(req.body.email, req.body.password).then(user => { 

    // save user information in the session 
    req.session.user = user; 
    req.session.authenticated = true; 

    return res.json({ 
     user:user, 
     token:token 
    }); 
}).catch(err => { 
    sails.log.error(err); 
    res.json(403, { 
    callstack: err.callstack, 
    error: 'Authentication error', 
    reason : err.reason 
    }); 
}); 

Dieser meine Politik für die anderen Seiten (nach Anmeldung):

module.exports = function(req, res, next) { 

    // User is allowed, proceed to the next policy, 
    if (req.session.authenticated && req.session.user) { 
     return next(); 
    } 

    // User is not allowed 
    return res.forbidden('You are not permitted to perform this action. (Authenticated)'); 
    }; 

Das Problem werden, dass die Sitzungsdaten nicht zum ersten gespeichert Anfrage Bedeutung Ich bekomme 403 verboten nur nach dem ersten erfolgreichen Login. Daraufhin muss ich mich abmelden und dann erneut anmelden, damit die Sitzungsdaten angezeigt werden.

Das Problem ist nicht beschränkt auf die Anmeldung (mit Authentifizierungsrichtlinie), sondern gilt auch für jede Aktion, die die Sitzungsdaten mit oder ohne Richtlinie erfordert. Und tritt für jede neue Sitzung auf - nicht nur beim ersten Hochfahren des Servers.


Ich dachte, das Problem mit Speicher-Sitzung zurückzuführen war, so habe ich versucht, auch Sail.js konfigurieren mit Redis als Session-Speicher zu arbeiten, indem sie die config/session.js der folgenden ändern:

adapter: 'redis', 

    // host: 'localhost', 
    // port: 6379, 
    // ttl: 60*60*20, 
    // db: 0, 
    // prefix: 'sess:', 

unkommentiert ich die Adapter Linie und versuchte, mit und ohne die optionalen redis Verbindungsparameter, aber dann wurde die req.session undefined erklärt überall

+0

nicht sicher, was passiert So etwas habe ich noch nie erlebt. Aber warum legen Sie keine Sitzungsinformationen in ein JWT-Token? Wie ich sehen kann, verwenden Sie Token-Logik ... – hlozancic

+0

Ich nehme an, dass das ein Workaround sein kann und einfach in JWT-Token setzen, aber dann das etwas den Zweck der Segel besiegt ... – Aaron

+0

Meine Vermutung wäre, dass Sie eine Race-Bedingung haben Für dieselbe Sitzung werden zwei Cookies gesetzt. Vielleicht ein Lade-Spinner am Frontend, der einen Webfont für sein Icon lädt, oder ein anderes Asset wie ein Bild, das dynamisch geladen wird, wenn Sie auf "Senden" klicken, um sich einzuloggen -loaded _before_ der Benutzer sendet das Login-Formular. – sgress454

Antwort

0

ich den connect-mongo-Adapter und ein ähnliches Problem gefunden. Der Grund ist, weil, wenn Sie req.session.user = user verwenden der Hintergrundcode Ihre Sitzung in DB (in meinem Fall Mongo, in Ihrem Redis) und vor es endet, führt Ihr Code den res.json Teil.

mit der asynchronen Code der DB-Einsparung zu begegnen, versuchen, so etwas zu tun (haben Sie Ihren Code nicht getestet, aber das zu meinem Fall löste das Problem zu tun):

AuthService.login(req.body.email, req.body.password).then(user => { 

    // save user information in the session 

    // this is on memory 
    req.session.user = user; 
    req.session.authenticated = true; 

    // now the session is saved in DB 
    req.session.save(function() { 
     return res.json({ 
     user:user, 
     token:token 
     }); 
    } 
    }).catch(err => { 
    sails.log.error(err); 
    res.json(403, { 
    callstack: err.callstack, 
    error: 'Authentication error', 
    reason : err.reason 
    }); 
}); 
Verwandte Themen