我使用Passport.js认证(本地策略),并与摩卡和Supertest测试。
我怎样才能创建一个会话,并与Supertest认证的请求?
我使用Passport.js认证(本地策略),并与摩卡和Supertest测试。
我怎样才能创建一个会话,并与Supertest认证的请求?
您应该使用的SuperAgent了点。 它是低级别模块,并通过使用supertest
。 看看节坚持一个代理 :
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
});
现在你可以使用user1
进行认证的请求。
作为zeMirco指出,潜在superagent
模块支持会话,自动保持你的cookies。 然而,也可以使用superagent.agent()
从功能supertest
,通过一个未记录的功能。
只需使用require('supertest').agent('url')
而不是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();
}
};
};
试试这个,
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();
});
作为附录安迪的回答,才能有Supertest启动你的服务器,你可以做到这一点是这样的:
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();
});
});
});
我很抱歉,但没有建议的解决方案并不为我工作。
随着supertest.agent()
我不能使用的app
实例,我需要事先运行服务器,并指定http://127.0.0.1:port
,而且我不能使用supertest的预期(断言),我不能使用supertest-as-promised
lib和等等...
该cookies
情况下也不会在所有的工作对我来说。
所以,我的解决办法是:
如果您正在使用Passport.js,它利用了“承载令牌”机制,您可以在您的规格使用下面的例子:
var request = require('supertest');
var should = require('should');
var app = require('../server/app.js'); // your server.js file
describe('Some auth-required API', function () {
var token;
before(function (done) {
request(app)
.post('/auth/local')
.send({
email: 'test@example.com',
password: 'the secret'
})
.end(function (err, res) {
if (err) {
return done(err);
}
res.body.should.to.have.property('token');
token = res.body.token;
done();
});
});
it('should respond with status code 200 and so on...', function (done) {
request(app)
.get('/api/v2/blah-blah')
.set('authorization', 'Bearer ' + token) // 1) using the authorization header
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) {
return done(err);
}
// some `res.body` assertions...
done();
});
});
it('should respond with status code 200 and so on...', function (done) {
request(app)
.get('/api/v2/blah-blah')
.query({access_token: token}) // 2) using the query string
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) {
return done(err);
}
// some `res.body` assertions...
done();
});
});
});
您可能希望有一个辅助函数来验证用户:
test/auth-helper.js
'use strict';
var request = require('supertest');
var app = require('app.js');
/**
* Authenticate a test user.
*
* @param {User} user
* @param {function(err:Error, token:String)} callback
*/
exports.authenticate = function (user, callback) {
request(app)
.post('/auth/local')
.send({
email: user.email,
password: user.password
})
.end(function (err, res) {
if (err) {
return callback(err);
}
callback(null, res.body.token);
});
};
有一个富有成效的一天!
我会假设你正在使用的CookieSession中间件。
作为平头提到的,你的目标是获得一个cookie值传递到您的要求。 然而,无论出于何种原因(至少在我的测试),supertest将不会触发在同一个测试2个请求。 所以,我们必须进行逆向工程如何得到正确的cookie的值。 首先,你需要为需要构建您的Cookie模块:
var Cookie = require("express/node_modules/connect/lib/middleware/session/cookie")
, cookieSignature = require("express/node_modules/cookie-signature")
是的,这是丑陋的。 我把那些在我的测试文件的顶部。
接下来,我们需要构建的cookie的值。 我把这个变成一个beforeEach
对于需要身份验证的用户测试:
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
在我的部分是以前定义beforeEach
是定义我要“登录”用户链。 的结构session
是护照(至少目前)如何插入当前用户信息到您的会话。
该var val
线, "j:"
和"s:"
都拆出来连接CookieSession中间件的护照将回退到上,如果你正在使用基于Cookie的会话。 最后,我们序列化饼干。 我把"session"
在那里,因为这是我如何配置我的Cookie会话中间件。 此外, App.config.cookieSecret
在别处定义,它必须是传递给您的快递/连接CookieSession中间件的秘密。 我藏入Test.cookie
,这样我以后可以访问它。
现在,在实际测试中,你需要使用的cookie。 例如,我有以下测试:
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
}
注意调用set
与"cookie"
和Test.cookie
。 这将导致使用我们构建的cookie中的请求。
现在你已经伪造了您的应用程序,以为用户登录,和你没有保持一个实际的服务器上运行。