J'utilise Passport.js pour l'authentification (stratégie locale) et les tests avec Mocha et Supertest.
Comment créer une session et faire des requêtes authentifiées avec Supertest?
J'utilise Passport.js pour l'authentification (stratégie locale) et les tests avec Mocha et Supertest.
Comment créer une session et faire des requêtes authentifiées avec Supertest?
Comme le souligne zeMirco, le module sous-jacent superagent
prend en charge les sessions et gère automatiquement les cookies pour vous. Cependant, il est possible d'utiliser la fonctionnalité superagent.agent()
de supertest
, via une fonctionnalité non documentée.
Utilisez simplement require('supertest').agent('url')
au lieu de require('supertest')('url')
:
var request = require('supertest');
var server = request.agent('http://localhost:3000');
describe('GET /api/getDir', function(){
it('login', loginUser());
it('uri that requires user to be logged in', function(done){
server
.get('/api/getDir')
.expect(200)
.end(function(err, res){
if (err) return done(err);
console.log(res.body);
done()
});
});
});
function loginUser() {
return function(done) {
server
.post('/login')
.send({ username: 'admin', password: 'admin' })
.expect(302)
.expect('Location', '/')
.end(onResponse);
function onResponse(err, res) {
if (err) return done(err);
return done();
}
};
};
Vous devriez utiliser superagent pour cela. C'est un module de niveau inférieur et utilisé par supertest
. Jetez un coup d’œil à la section Persistance d’un agent :
var request = require('superagent');
var user1 = request.agent();
user1
.post('http://localhost:4000/signin')
.send({ user: 'hunter@hunterloftis.com', password: 'password' })
.end(function(err, res) {
// user1 will manage its own cookies
// res.redirects contains an Array of redirects
});
Vous pouvez maintenant utiliser user1
pour faire des demandes authentifiées.
Essaye ça,
var request=require('supertest');
var cookie;
request(app)
.post('/login')
.send({ email: "user@gluck.com", password:'password' })
.end(function(err,res){
res.should.have.status(200);
cookie = res.headers['set-cookie'];
done();
});
//
// and use the cookie on the next request
request(app)
.get('/v1/your/path')
.set('cookie', cookie)
.end(function(err,res){
res.should.have.status(200);
done();
});
En complément de la réponse d'Andy, pour que Supertest démarre votre serveur à votre place, procédez comme suit:
var request = require('supertest');
/**
* `../server` should point to your main server bootstrap file,
* which has your express app exported. For example:
*
* var app = express();
* module.exports = app;
*/
var server = require('../server');
// Using request.agent() is the key
var agent = request.agent(server);
describe('Sessions', function() {
it('Should create a session', function(done) {
agent.post('/api/session')
.send({ username: 'user', password: 'pass' })
.end(function(err, res) {
expect(req.status).to.equal(201);
done();
});
});
it('Should return the current session', function(done) {
agent.get('/api/session').end(function(err, res) {
expect(req.status).to.equal(200);
done();
});
});
});
Je vais supposer que vous êtes à l'aide de la CookieSession middleware.
Comme grub mentionné, votre objectif est d'obtenir une valeur du cookie à transmettre à votre demande. Cependant, pour quelque raison que ce soit (au moins dans mes tests), supertest ne se déclenche pas à 2 demandes dans le même test. Donc, nous avons à désosser comment faire pour obtenir la bonne valeur du cookie. Tout d'abord, vous aurez besoin de demander les modules pour la construction de votre cookie:
var Cookie = require("express/node_modules/connect/lib/middleware/session/cookie")
, cookieSignature = require("express/node_modules/cookie-signature")
Oui, c'est laid. J'ai mis ceux en haut de mon fichier de test.
Ensuite, nous avons besoin de construire la valeur du cookie. - Je mettre ceci en beforeEach
pour les tests qui aurait besoin d'un utilisateur authentifié:
var cookie = new Cookie()
, session = {
passport: {
user: Test.user.id
}
}
var val = "j:" + JSON.stringify(session)
val = 's:' + cookieSignature.sign(val, App.config.cookieSecret)
Test.cookie = cookie.serialize("session",val)
Test.user.id
a été défini précédemment dans la partie de mon beforeEach
chaîne que défini à l'utilisateur que j'allais "login". La structure de l' session
est comment Passeport (au moins actuellement) insère l'utilisateur actuel de l'information dans votre session.
L' var val
lignes avec "j:"
et "s:"
sont arrachées de la Connecter CookieSession middleware Passeport de secours sur si vous êtes en utilisant des cookies de sessions. Enfin, nous sérialiser le cookie. J'ai mis "session"
là-dedans, parce que c'est comment j'ai configuré mon cookie de session middleware. Aussi, App.config.cookieSecret
est définie nulle part ailleurs, et il doit être le secret que vous transmettez à votre Express/Connect CookieSession middleware. Je planque en Test.cookie
afin que je puisse y accéder plus tard.
Maintenant, dans le test réel, vous devez utiliser le cookie. Par exemple, j'ai le test suivant:
it("should logout a user", function(done) {
r = request(App.app)
.del(App.Test.versionedPath("/logout"))
.set("cookie", Test.cookie)
// ... other sets and expectations and your .end
}
Notez que l'appel à set
avec "cookie"
et Test.cookie
. Qui sera la cause de la demande pour utiliser le cookie nous avons construit.
Et maintenant, vous avez troqué votre application en pensant que l'utilisateur est connecté, et vous n'avez pas à garder un serveur en cours d'exécution.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.