我想了解有关处理用户登录和注册请求的一些最佳实践。
例如,如果用户尝试使用其电子邮件注册,并且其帐户已存在,则会发生什么情况?我的服务器应该reject
请求吗?还是我应该使用一些状态代码满足请求,并在客户端处理它?
目前,我下面的代码将满足请求并发送自定义消息,我从客户端处理它
app.post('/signup', (req, res) => {
const email = req.body.email
const plainTextPassword = req.body.password;
//check if user already exists
User.find({ email: email }, (err, existingUser) => {
//account doesnt exist
if (existingUser.length === 0) {
bcrypt.hash(plainTextPassword, saltRounds, async (err, hash) => {
try {
const user = new User({
email: email,
password: hash
});
let result = await user.save();
if (result) {
res.send(result)
}
} catch (e) {
res.send(e);
}
})
} else {
//notify user that account exists
res.json("account exists")
}
})
})
我在哪里可以阅读有关此类做法的更多信息? 谢谢
HTTP 对此有一些约定,但在选择如何发出信号方面仍然有很大的灵活性。此外,许多开发人员坦率地忽略了这些约定,并且一直在编造疯狂的废话,例如即使对于完全损坏的请求也返回200 OK
- 只要他们自己的代码是唯一的消费者,通常无关紧要。你可以而且应该做得更好,但如果你不这样做,软件警察就不会来追捕你。
HTTP 定义了服务器可以使用的一堆状态代码。
处理此问题的一种方法是返回409 Conflict
,在这种情况下,这将被解释为"您要求我为已声明的标识符创建一个帐户"。
这是诚实的,但确实有一个缺点:它允许邪恶的人找出哪些电子邮件帐户已经注册了您。因此,尽管我会说这是完美的响应代码,但您可能不能使用它,因为它侵犯了用户的隐私。
400 Bad Request
不太诚实(您通常希望将其保留给形状不佳的请求 - 缺少数据或错误的数据类型),并且具有与409
相同的问题:它允许攻击者确认是否已声明特定标识符。
因此,在设置用户帐户时,只要请求格式正确,您可能必须始终发出成功的信号,但 UI 随后需要对其表示形式进行对冲:而不是对用户说"帐户创建成功!",它可能需要说"确认电子邮件已发送到 [该地址] 以帮助您完成帐户设置。
然后,当且仅当该地址尚未注册时,您才会向该帐户发送验证您的电子邮件。
我应该补充一点:当您谈论注册帐户而不是基本上任何其他类型的 REST 时,非常特殊的规则适用。如果您正在构建一个跟踪蛋糕食谱的微服务,您可能会遵循更直接的规则。但是,帐户注册必然会拖累各种极其重要的安全和隐私考虑因素,迫使您的端点...谨慎到不诚实的地步。