2013-06-24 9 views
6

Does passport.js richiede affinità di sessione quando distribuito su più istanze Node.js? Quando utilizzo l'affinità di sessione, l'autenticazione funziona correttamente con più istanze (dietro un sistema di bilanciamento del carico). Sto usando redis come archivio di sessioni. Tuttavia, quando non si utilizza l'affinità di sessione, passport.js non riesce con l'errore indicato di seguito. Con una sola istanza funziona sempre. C'è un modo per far funzionare passport.js senza affinità di sessione.Does passport.js richiede affinità di sessione quando distribuito su più istanze node.js

500 Failed to verify assertion (message: Invalid association handle) 

    at Strategy.authenticate.identifier (node_modules/passport-google/node_modules/passport-openid/lib/passport-openid/strategy.js:184:36) 
    at _verifyAssertionData (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1053:12) 
    at _verifyAssertionAgainstProvider (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1178:14) 
    at _checkSignatureUsingAssociation (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1229:14) 
    at Object.openid.loadAssociation (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:111:5) 
    at _checkSignatureUsingAssociation (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1221:10) 
    at _checkSignature (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1211:5) 
    at _verifyAssertionAgainstProvider (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1174:3) 
    at _verifyDiscoveredInformation node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:1145:16) 
    at openid.discover (node_modules/passport-google/node_modules/passport-openid/node_modules/openid/openid.js:668:7) 

Il passaporto frammento di codice utilizzando:

app.set('port', process.env.PORT || 8080); 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'ejs'); 
app.use(express.favicon()); 
app.use(express.logger('dev')); 
app.use(express.query()); 
app.use(express.bodyParser()); 
app.use(express.methodOverride()); 
app.use(express.cookieParser()); 
app.use(express.session({ key: 'JSESSIONID', secret: '****', cookie : {httpOnly:false, 
    maxAge: 5*60*1000, path: '/'}, 
    store: new RedisStore({ prefix: 'sid:', client: redisClient }) 
        })); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(app.router); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.get('/auth/google', passport.authenticate('google')); 
app.get('/auth/google/return', 
     passport.authenticate('google', { successRedirect: '/success', 
             failureRedirect: '/login' })); 

Ho anche serializeUser e deserializeUser che utilizza Redis negozio a negozio/recuperare oggetto utente - ma questo errore sta accadendo quando il provider di identità reindirizza indietro al callback URI. Sto distribuendo la mia app in AppFog e impostando l'affinità della sessione utilizzando la chiave cookie JSESSIONID (è così che funzionano i bilanciatori del carico cloudfoundry). Se uso un'altra chiave (che significa che l'affinità di sessione è disattivata), allora l'errore viene generato da passport.js.

+0

Dovresti riuscire a eseguire senza affinità. Penso che sarebbe d'aiuto se potessimo vedere come stai usando i redis per archiviare e condividere sessioni. Le linee di codice pertinenti possono aiutare. –

+0

Ho aggiunto lo snippet di codice oltre a qualche spiegazione più breve della situazione. Qualsiasi aiuto sarebbe apprezzato. – jrajp2184

+0

Un'altra nota importante: i provider di facebook e twitter funzionano senza affinità di sessione (entrambi utilizzano OAuth). Il problema si verifica con l'autenticazione di Google (OpenID). A volte funziona con google, ma quello che presumo è quando sia la richiesta originale che il reindirizzamento vengono elaborati dalla stessa istanza. – jrajp2184

risposta

7

Penso di averlo risolto. C'è un'opzione: "senza stato" che può essere passato a GoogleStrategy. L'ho capito guardando la fonte: https://github.com/jaredhanson/passport-openid/blob/master/lib/passport-openid/strategy.js. Pertanto l'istanziazione di GoogleStrategy deve essere:

new GoogleStrategy({ 
    returnURL: BASE + '/auth/google/return', 
    realm: BASE + "/", 
    stateless: true 
} 

Grazie a Jared Hanson per l'implementazione di tale opzione! (speriamo che venga documentato nel sito principale).

+0

Ciò è stato utile con un'app multi-dyno su Heroku. Stavo ottenendo lo stesso errore usando Mongo come archivio di sessioni. – tbeseda

Problemi correlati