我尝试根据这个项目编写用户名/密码认证服务器:
https://github.com/tutsplus/passport-mongo.git
但是我总是会收到“发送后无法设置标头”。错误。
我不想使用任何登录会话,所以我删除了与之相关的所有代码。
这是我的代码:
在app.js
......
// Configuring Passport
var passport = require('passport');
app.use(passport.initialize());
// Initialize Passport
var initPassport = require('./libs/auth/init');
initPassport(passport);
var routes = require('./routes/index')(passport);
app.use('/api', routes);
......
在./libs/auth/init.js中:
var signin = require('./signin');
var createuser = require('./createuser');
var User = require('../../models/user');
module.exports = function(passport) {
// Setting up Passport Strategies for Login and SignUp/Registration
signin(passport);
createuser(passport);
};
signin.js:
var LocalStrategy = require('passport-local').Strategy;
var User = require('../../models/user');
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport) {
passport.use('signin', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
// check in mongo if a user with username exists or not
User.findOne({'username' : username},
function(err, user) {
// In case of any error, return using the done method
if (err) {
return done(err);
}
// Username does not exist, log the error and redirect back
if (!user) {
console.log('User Not Found with username ' + username);
return done(null, false);
}
// User exists but wrong password, log the error
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null, false); // redirect back to login page
}
// User and password both match, return user from done method
// which will be treated like success
return done(null, user);
}
);
})
);
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
}
};
,与原始项目几乎相同
createuser.js与原始项目几乎相同:
var LocalStrategy = require('passport-local').Strategy;
var User = require('../../models/user');
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport) {
passport.use('createuser', new LocalStrategy({
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
var findOrCreateUser = function() {
// find a user in Mongo with provided username
User.findOne({'username' : username}, function(err, user) {
// In case of any error, return using the done method
if (err) {
console.log('Error in SignUp: ' + err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists with username: ' + username);
return done(null, false);
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
// save the user
newUser.save(function(err) {
if (err) {
console.log('Error in Saving user: ' + err);
throw err;
}
console.log('User Registration successful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute the method
// in the next tick of the event loop
process.nextTick(findOrCreateUser);
})
);
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
}
};
模型文件:
var mongoose = require('mongoose');
module.exports = mongoose.model('User',{
id: String,
username: String,
password: String
});
./routes/index.js与原始文件非常不同。因为我试图实现用户身份验证apis,我想在用户身份验证后发回一些json数据,而不是将它们重定向到另一个URL。
var express = require('express');
var router = express.Router();
module.exports = function(passport) {
router.post('/signin', function(req, res, next) {
passport.authenticate('signin', {session : false},
function(err, user, info) {
if (err) {
res.json({
message: "Internal Server Error!"
})
} else if (!user) {
res.json({
message: "No Such User!"
})
}
req.logIn(user, function(err) {
if (err) {
res.json({
message: "Login Failure!"
})
}
res.json({
message: "Login Success!"
})
});
})(req, res, next);
});
router.post('/createuser', function(req, res, next) {
passport.authenticate('createuser', {session : false},
function(err, user, info) {
if (err) {
res.json({
message: "Internal Server Error!"
})
} else if (!user) {
res.json({
message: "User Creation failure!"
})
}
res.json({
message: "Create User Success!"
})
})(req, res, next);
});
return router;
};
然而,这看起来效果不佳。对于signin api,每次我从curl发出请求时都会收到该错误消息,例如:
curl --data "username=2232&password=223" http://localhost:3000/api/signin
仅当create user成功时,对于createuser api,它不会崩溃。否则我仍会收到该错误消息。
顺便说一下,我不知道在幕后做了什么方法。任何人都可以给我一些细节吗?如果有人也能回答这个问题,我将不胜感激: 这是我第一次尝试设计web api。我想做的事情对我来说似乎很奇怪:服务器收到一个用户名和密码,然后它在数据库中查找,如果找到它然后告诉客户“嘿,我找到你了!”。然后没有副作用发生。
我不认为这是认证api如何工作的正确方法。我希望服务器生成某种访问密钥以及到期时间。但是我没有发现passport.js有能力做到这一点。我是否使用错误的lib与node.js进行身份验证api?
答案 0 :(得分:1)
在您的路径文件中,您需要在发送响应时使用return
,因为只是调用res.json
方法,函数的执行不会停止,服务器会尝试发送两个响应,即&#39 ; s错误告诉你的是什么。
你应该修改你的代码:
router.post('/signin', function(req, res, next) {
passport.authenticate('signin', {session : false},
function(err, user, info) {
if (err) {
return res.json({
message: "Internal Server Error!"
})
} else if (!user) {
return res.json({
message: "No Such User!"
})
}
req.logIn(user, function(err) {
if (err) {
return res.json({
message: "Login Failure!"
})
}
return res.json({
message: "Login Success!"
})
});
})(req, res, next);
});
router.post('/createuser', function(req, res, next) {
passport.authenticate('createuser', {session : false},
function(err, user, info) {
if (err) {
return res.json({
message: "Internal Server Error!"
})
} else if (!user) {
return res.json({
message: "User Creation failure!"
})
}
return res.json({
message: "Create User Success!"
})
})(req, res, next);
});