c# - 如何在 ASP.NET 核心 MVC 中使用一次性密码 (OTP) 注册手机号码,而不是使用 2FA
问题描述
我正在 ASP.Net 核心 MVC 中创建一个应用程序,该应用程序需要用户注册并仅通过输入他们的手机来使用 OTP 进行验证。
我目前正在使用 Twilio 发送 SMS(不想使用 Twilio 仅验证 Twilio SMS)并且我正在通过随机生成 4 位数字来创建自己的 OTP。
所以我的问题是:如何使用我在手机上获得的这个 4 位 OTP 并注册手机并确保用户已登录?
我目前不想实施 2FA,因为它需要用户名和密码。
这个问题类似于:'https://stackoverflow.com/questions/43862276/register-with-phone-number-instead-of-email-using-mvc-identity' 但它已经过去了 4 年没有答案.. .
感谢任何帮助、提示或/和更多资源,在此先感谢!
解决方案
OTP 和用户登录/注册是两个独立的过程。由开发人员决定如何连接 OTP 和登录/注册。几个月前我已经实现了这个要求。您可以这样做:
- 第一步:用户输入一个有效的电话号码。然后将用户重定向到可以输入 OTP 的屏幕(可选 - 上一步中的电话号码可以在隐藏字段中)
- 第二步:生成 4 位 OTP 并将电话号码和 OTP 存储在数据库中,我们将其称为“OTP”表。将 OTP 发送给用户
- 第三步:在 OTP 输入屏幕上,用户输入 OTP
- 第 4 步:检查“OTP”表中的 OTP。如果 OTP 有效,则:
-
- 如果电话号码存在于“用户”表中,则这是回访用户。在第 5 步中登录此用户。您已经在“用户”表中拥有此用户 ID
-
- 如果“用户”表中不存在电话号码,则仅使用电话号码创建用户配置文件(您可以稍后获取其他信息,如姓名)。之后在步骤 5 中登录用户
- 第五步:登录用户。为此,您只需要一个您在上一步中已经拥有的用户实体。要登录,您可以实现任何登录提供程序。我建议使用 JWT (JSON Web Token) 进行身份验证。
当您拥有已成功验证 OTP 的用户时,使用用户 ID 对用户进行身份验证。以下是实现 JWT 的方法:
private string GenerateJSONWebToken(UserModel userInfo)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Issuer"],
null,
expires: DateTime.Now.AddMinutes(120),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
这将生成一个有效期为 120 分钟的令牌,如下所示:
{
"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJKaWduZXNoIFRyaXZlZGkiLCJlbWFpbCI6InRlc3QuYnRlc3RAZ21haWwuY29tIiwiRGF0ZU9mSm9pbmciOiIwMDAxLTAxLTAxIiwianRpIjoiYzJkNTZjNzQtZTc3Yy00ZmUxLTgyYzAtMzlhYjhmNzFmYzUzIiwiZXhwIjoxNTMyMzU2NjY5LCJpc3MiOiJUZXN0LmNvbSIsImF1ZCI6IlRlc3QuY29tIn0.8hwQ3H9V8mdNYrFZSjbCpWSyR1CNyDYHcGf6GqqCGnY"
}
将 JSON 令牌发送到应用程序/移动应用程序。只要应用程序/移动应用程序具有令牌并将其与请求(在标头中)一起发送,应用程序和用户就会通过身份验证。您必须根据数据库表检查令牌及其有效性。这是JWT 部分的完整实现。
推荐阅读
- c# - 将 C# 类库嵌入到程序集中并动态加载它们
- arrays - 带有搜索器的 Tableview - 搜索效果很好,但选择元素显示错误的元素
- java - 在生产中我得到 slf4j 记录器工厂,但在开发中我总是得到 logback 工厂
- angular-material - 如何删除轮廓垫形边框角半径
- javascript - 如何删除影响 React 元素的 Jquery 文档单击侦听器?
- typescript - 如何将流转换为打字稿
- ios - Swift CGAffineTransform 旋转跳跃
- python - 为什么我的 sklearn 库中的分类特征返回了意外的关键字参数?
- c - 取消引用时,转换为 char 指针的 void 指针崩溃
- c - linux内核中具有相同签名的函数