获取客户端上的令牌以进行通行证本地authentication

编辑我试了两个,redirect,而不是redirect。 当redirect时,我得到的结果与我直接请求/结果相同,但当我收到的data = Moved Temporarily. Redirecting to /不是包含data = Moved Temporarily. Redirecting to /的对象时data = Moved Temporarily. Redirecting to / data = Moved Temporarily. Redirecting to /

鉴于这一战略:

 var strategy = new LocalStrategy( { session: true }, function (username, password, done) { User.findOne({ username: username }, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Incorrect username.' }); } if (user.password !== password) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, user); }); }); 

而这个服务器:

 //************ EDIT ****// function genuuid(req) { return "Test UID"; } //************ EDIT ****// var app = express(); var router = express.Router(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(passport.initialize()); //************ EDIT ****// app.use(session({ genid: function(req) { return genuuid() // use UUIDs for session IDs }, secret: "somethingSecret", cookie: {maxAge: 60000 }, resave: true, saveUninitialized: false })); //************ EDIT ****// passport.use(strategy); passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })); server = http.createServer(app).listen(port, function(){ console.log('Express server listening on port ' + app.get('port')); }) 

我试图从我的客户端(摩卡testing)得到这样的生成令牌:

 it('Login should redirect to home and return a user token', function(done) { var postData = querystring.stringify({ username : user, password : password }); var options = { uri: 'http://' + hostname + ':' + port + '/login', followRedirect: false }; request.post(options) .form(postData) .on('response', function(res) { res.statusCode.should.equal(302); }) .on('data',function(data) { should.exist(data); should.fail(0,1,'Test not implemented'); done(); }) .on('error', function(e) { should.fail(0,1,'Problem with request: ' + e.message); }); }); 

标题包含

 { 'x-powered-by': 'Express', location: '/', vary: 'Accept', 'content-type': 'text/plain; charset=utf-8', 'content-length': '35', date: 'Tue, 08 Sep 2015 19:46:03 GMT', connection: 'keep-alive' } 

没有cookies或什么的。 我的代币在哪里?

尝试使用会话中间件进行会话,例如快速会话 :

 var session = require('express-session'); // Code to set up your app var app = express(); // Make sure to replace "somethingSecret" with your own secret value app.use(session({secret: "somethingSecret", resave: true, saveUnitialized: false})); 

我写了一个非常接近你提供的应用程序,看到了同样的问题,这是我很奇怪,因为我以前多次使用快递和护照。 当我意识到我没有使用任何会话中间件时,我添加了express-session中间件和voila ; set-cookie头。

但请注意,此代码实际上尚未准备好生产。 从express-session存储库:

警告默认的服务器端会话存储器MemoryStore故意不是为生产环境而devise的。 它会在大多数情况下泄漏内存,不会通过单个进程扩展,而是用于debugging和开发。

有关商店列表,请参阅兼容的会话商店 。

[编辑]

使用此代码(用户被stubbed始终返回相同的值):

 var bodyParser = require('body-parser'); var express = require('express'); var http = require('http'); var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var session = require('express-session'); // Stub of User schema for testing var User = { findOne: function(user, callback) { callback(null, { id: 1234, username: user.username, password: 'foo' }); }, findById: function(id, callback) { callback(null, { id: 1234, username: 'user', password: 'foo' }); } }; var strategy = new LocalStrategy( { session: true }, function (username, password, done) { User.findOne({ username: username }, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Incorrect username.' }); } if (user.password !== password) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, user); }); }); function genuuid(req) { return "Test UID"; } var app = express(); var router = express.Router(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(passport.initialize()); app.use(session({ genid: function(req) { return genuuid() // use UUIDs for session IDs }, secret: "somethingSecret", cookie: {maxAge: 60000 }, resave: true, saveUninitialized: false })); passport.use(strategy); passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })); server = http.createServer(app).listen(51015, function(){ console.log('Express server listening on port ' + app.get('port')); }); 

运行testing:

 var should = require('should'); var assert = require('assert'); var request = require('request'); var querystring = require('querystring'); it('Login should redirect to home and return a user token', function(done) { var postData = querystring.stringify({ username : 'user', password : 'foo' }); var options = { uri: 'http://' + '127.0.0.1' + ':' + '51015' + '/login', followRedirect: false }; request.post(options) .form(postData) .on('response', function(res) { console.log(res.headers); res.statusCode.should.equal(302); }) .on('data',function(data) { should.exist(data); should.fail(0,1,'Test not implemented'); done(); }) .on('error', function(e) { should.fail(0,1,'Problem with request: ' + e.message); }); }); 

给出以下输出; 注意set-cookie头包含在内:

 mocha { 'x-powered-by': 'Express', location: '/', vary: 'Accept', 'content-type': 'text/plain; charset=utf-8', 'content-length': '35', 'set-cookie': [ 'connect.sid=s%3ATest%20UID.NC0hY3rYGMdnN560ewpf%2FaJbO%2BNd9M7QLz3gnse0eLs; Path=/; Expires=Wed, 09 Sep 2015 13:08:06 GMT; HttpOnly' ], date: 'Wed, 09 Sep 2015 13:07:06 GMT', connection: 'close' } 1) Login should redirect to home and return a user token 0 passing (69ms) 1 failing 1) Login should redirect to home and return a user token: Uncaught AssertionError: Test not implemented 

除了User模式和硬编码的configuration值之外,我的代码应该和你的代码一样,所以我不知道如何得到set-cookie头文件。

您是否正在使用任何其他可能会影响会话或Cookie的中间件?

[编辑2]

问题是(在你的版本库中 )你添加的session中间件的版本与server.listen的版本不同,因此对app的更改实际上并没有影响。

不要让服务器在一组testing之前开始监听,而应该让每个testing都启动一次 ,然后立即将所有需要的parameter passing给它。 我已经提交了一个pull请求到你的版本库,详细介绍了我可能会这样做,因为它不是less量的代码,并不是真正理想的粘贴在这里。

请花些时间阅读和理解这些更改,因为我只关心使会话令牌被发送,我不能保证其他function是否受到这些更改的影响。