我目前正在使用此代码登录:
passport.use(new localStrategy({
usernameField: 'username'
}, User.authenticate()));
Run Code Online (Sandbox Code Playgroud)
当我使用用户名和密码登录时,这很好用。现在我想用电子邮件而不是用户名登录。我已将代码更改为:
passport.use(new localStrategy({
usernameField: 'email',
usernameQueryFields: ['email']
}, User.authenticate()));
Run Code Online (Sandbox Code Playgroud)
我还更改了我的 HTML 代码以显示带有电子邮件名称的电子邮件字段:
<input type="text" name="email" id="email" placeholder="Your Email" class="form-control">
Run Code Online (Sandbox Code Playgroud)
这是我的用户的架构:
{
"_id" : ObjectId("585f62d63158ec1f608f82a2"),
"salt" : "d7fd24ab337be7341bb6c54df69eccdce607a6cffc8457be4d44",
"hash" : "(long text)",
"username" : "joseph320",
"email" : "joseph@gmail.co",
"name" : "joseph",
"__v" : 0,
}
Run Code Online (Sandbox Code Playgroud)
所以现在它应该在数据库中查找电子邮件字段,并将其与登录表单中提供的电子邮件用户进行比较。但它不起作用。当我尝试使用电子邮件和密码登录时,它给了我“无效的用户名或密码”错误。
但是当我尝试使用用户名和确切密码登录时,它会成功登录。问题出在哪里,我该如何解决?
我正在使用此软件包进行身份验证:
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"passport-local-authenticate": "^1.2.0",
"passport-local-mongoose": "^4.0.0",
Run Code Online (Sandbox Code Playgroud) 我想使用用户的电子邮件和密码登录。但在护照中你应该使用用户名。
我已经尝试了很多关于如何做到这一点的例子。但没有工作。真正的问题是当应用程序想要将记录保存到数据库中时。尽管我已更改代码以查找电子邮件而不是用户名字段,但这是保存到数据库的最终记录:
'name': 'joseph',
'username' : 'example@gmail.com',
.
.
Run Code Online (Sandbox Code Playgroud)
但我不希望电子邮件被保存为用户名。当我在用户注册后用 mongoose 更改它时,它是正确的,但是当应用程序想要对用户进行身份验证时,问题又会出现。
它将在数据库而不是电子邮件中查找用户名字段。因为用户将提供电子邮件作为用户名,所以登录将失败。
代码:
app.get("/register", function(req, res) {
var newUser = new User({
username : req.body.username,
email : req.body.email,
name: req.body.name
});
User.register(newUser, req.body.password, function(err, user) {
if (err) {
req.flash('error', "An error ocurred, please try again.");
return res.redirect('back');
} else {
passport.authenticate("local")(req, res, function() {
req.flash("success", "Welcome");
res.redirect("/admin");
});
}
});
});
Run Code Online (Sandbox Code Playgroud)
此代码以我想要的方式注册用户,但问题在于登录:
router.post('/login', middleware.outLoggedIn, passport.authenticate("local", {
successRedirect: "/admin",
failureRedirect: "/login",
failureFlash: "Invalid username or password",
successFlash: "Welcome!"
})); …Run Code Online (Sandbox Code Playgroud) 一个人可以来创建一个帐户.我在客户端实现了很好的验证,例如,如果他没有提供有效的电子邮件地址,我会立即通知他,这是无效的电子邮件(使用客户端JavaScript).
但攻击者很容易绕过客户端验证.所以我也在服务器端使用了相同的验证.但不同的是用户体验.例如,如果客户端上的JavaScript被禁用并且用户提供了无效的电子邮件,则应用程序将告诉他错误(在提交表单和刷新页面之后).没有更多信息.(因为我认为他是攻击者所以我的网站应该为攻击者提供糟糕的用户体验).
现在我的问题是:如果我这样做,我的网站的用户体验会好吗?(在客户端向用户报告错误,但在服务器端报告错误,服务器端将在整个表单提交任何失败的验证后返回'错误').
更多说明:
每当用户在输入中键入无效文本时,应用程序将在输入底部告诉他红色文本,他没有输入有效文本.(这将由于客户端JavaScript而发生).
但是,如果以某种方式禁用了客户端JavaScript并且用户在输入中键入了无效文本,则服务器端将在页面提交后向用户返回"错误".
node.js ×2
passport.js ×2
form-fields ×1
html ×1
javascript ×1
php ×1
security ×1
validation ×1