在处理api时进行双因素注册的正确方法是什么?
1)在前端有一个表单 - 电子邮件和电话 - 将数据发送到api方法
2)我有一个API,通过电子邮件和电话注册用户,生成代码并通过手机短信发送
问题 - 在前面检查短信代码的正确方法是什么? (发送代码作为寄存器的响应看起来不那么安全)
答案 0 :(得分:1)
我认为流程应该是(或多或少):
client:
- user fills out form and hits submit
- sends form data to backend
- show field for 2FA code entry
server:
- handles form data, generates a 2FA code, and sends that code to the client via email and/or SMS
- store that code in a DB (relational or not, doesn't really matter); you could even just store it whatever session manager you're using
- map that code to the current session, or supply that code to the client to correlate the 2FA code to the client
用户收到代码
client:
- user enters the code and hits submit
- sends entered code to the server
server:
- using the session or the DB, validates the code
- then, and only then, you auth the user
你是对的 - 永远不要在前端验证身份验证。
您的基本代码应该在前端看起来像这样:
class TwoFactorAuth extends React.Component {
state = { stage: 1 };
onSubmitStageOne = (data) => {
// goes to /
submit(data).then(() => {
this.setState({ stage: 2 });
});
}
onSubmitStageTwo = (data) => {
// goes to /auth
authenticate(data).then(() => {
// success
}).catch(() => {
// wrong code, try again
});
}
renderStageOne() {
return (
<form onSubmit={this.onSubmitStageOne}>
<input name="email" />
<input name="phone" />
</form>
)
}
renderStageTwo() {
return (
<form onSubmit={this.onSubmitStageTwo}>
<input name="code" />
</form>
)
}
render() {
return this.state.stage === 1 ?
this.renderStageOne() :
this.renderStageTwo();
}
}
需要注意的是,我正在使用ES6类和ES7类属性初始值设定项 - 如果要复制/粘贴上面的代码,则需要使用babel。
您的后端路线类似:
router.post("/", (req, res) => {
const code = utils.generate2FACode();
request.session["code"] = code;
utils.emailOrSMSUser(code);
res.sendStatus(200);
});
router.post("/auth", (req, res) => {
const code = req.session["code"];
if (code === req.body.code) {
req.session["signedIn"] = true; // simplified for demonstration
res.sendStatus(200);
} else {
res.sendStatus(401);
}
});
我在这里使用express
和express-session
。我会让你写generate2FACode
和emailOrSMSUser
。
编辑:whoops,你在标题中说PHP API - 类似逻辑,只用PHP而不是Node / Express。