在 client-side 上获取令牌以进行 passport-local 身份验证
Get token on the client-side for passport-local authentication
EDIT 我都试过了,重定向和不重定向。重定向时,我得到的结果与我直接请求 /
时的结果相同,当我没有收到时,我收到的是包含 data = Moved Temporarily. Redirecting to /
的 object
鉴于此策略:
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'));
})
我正在尝试从我的客户端(mocha 测试)获取生成的令牌,如下所示:
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);
});
});
Headers包含
{ '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' }
没有 cookie 或其他任何东西。我的代币在哪里?
尝试使用 session 中间件 session,例如 express-session:
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}));
我写了一个非常接近你提供的应用程序,看到了同样的问题,这对我来说很奇怪,因为我以前多次使用过快递和护照。当我意识到我没有使用任何 session 中间件时,我添加了 express-session
中间件和 voila; set-cookie
header.
但是请注意,此代码实际上尚未准备好投入生产。来自 express-session
存储库:
Warning The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
For a list of stores, see compatible session stores.
[编辑]
使用此代码(用户总是存根 return 相同的值):
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'));
});
运行 测试:
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
header 包括在内:
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
模式和硬编码的配置值,我的代码应该和你的一样,所以我有点不知所措你是如何没有得到 set-cookie
header.
您是否正在使用任何其他可能影响 session 或 cookie 的 express 中间件?
[编辑 2]
问题是(在您的 repository 中)您在与 server.listen
执行的范围不同的范围内添加 session
中间件,因此对 app
实际上没有影响。
不要让服务器在测试组之前开始监听,您应该让它为每个测试启动一次一次,并立即将您需要的所有参数传递给它。我已将 pull request 提交到您的存储库,其中包含我 可能 执行此操作的详细信息,因为它的代码量不小,并不是粘贴的理想选择在这里。
请花时间阅读并理解更改,因为我只关心发送 session 令牌,我不保证这些更改是否会影响其他功能。
EDIT 我都试过了,重定向和不重定向。重定向时,我得到的结果与我直接请求 /
时的结果相同,当我没有收到时,我收到的是包含 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'));
})
我正在尝试从我的客户端(mocha 测试)获取生成的令牌,如下所示:
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);
});
});
Headers包含
{ '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' }
没有 cookie 或其他任何东西。我的代币在哪里?
尝试使用 session 中间件 session,例如 express-session:
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}));
我写了一个非常接近你提供的应用程序,看到了同样的问题,这对我来说很奇怪,因为我以前多次使用过快递和护照。当我意识到我没有使用任何 session 中间件时,我添加了 express-session
中间件和 voila; set-cookie
header.
但是请注意,此代码实际上尚未准备好投入生产。来自 express-session
存储库:
Warning The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
For a list of stores, see compatible session stores.
[编辑]
使用此代码(用户总是存根 return 相同的值):
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'));
});
运行 测试:
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
header 包括在内:
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
模式和硬编码的配置值,我的代码应该和你的一样,所以我有点不知所措你是如何没有得到 set-cookie
header.
您是否正在使用任何其他可能影响 session 或 cookie 的 express 中间件?
[编辑 2]
问题是(在您的 repository 中)您在与 server.listen
执行的范围不同的范围内添加 session
中间件,因此对 app
实际上没有影响。
不要让服务器在测试组之前开始监听,您应该让它为每个测试启动一次一次,并立即将您需要的所有参数传递给它。我已将 pull request 提交到您的存储库,其中包含我 可能 执行此操作的详细信息,因为它的代码量不小,并不是粘贴的理想选择在这里。
请花时间阅读并理解更改,因为我只关心发送 session 令牌,我不保证这些更改是否会影响其他功能。