ASP.NET标识中的GenerateChangePhoneNumberToken方法生成重复的安全代码

时间:2016-02-17 15:08:53

标签: c# asp.net-mvc asp.net-identity

我们在MVC应用程序中使用ASP.net标识。每当用户更改电话号码或密码时,我们将通过电子邮件或SMS向用户发送安全码。我们将针对用户验证安全代码,如果有效,我们将允许用户更改电话号码或密码。

我们正在使用GenerateChangePhoneNumberToken身份提供的ASP.net方法生成安全代码。

var securityCode = UserManager.GenerateChangePhoneNumberToken(
                                                user.Id, model.MobileNumber);   

HTML

   <div class="text-center top-space" id="validate_code_email">
      <button id="send_via_email" class="submit-btn login-btn-align material_button" data-role="button" onclick="sendCodeViaEmail()">Send a New Code Via Email</button>
   </div>

JQuery的

 function sendCodeViaText() {          
        var model = { 'UserId': userIdentityId };
        $.ajax({
            url: "/api/accountwebapi/SendVerificationEmail",
            type: "POST",
            data: model,
            dataType: "json",
            success: function (data) {

            },
            error: function (e) {

            }
        });

API控制器方法发送安全码

  public IHttpActionResult SendVerificationEmail([FromBody] VerifyPhoneNumberViewModel model)
  {
       try
       {
           if (model != null)
           {
               var user = UserManager.Users.Where(a => a.Id == model.UserId).FirstOrDefault();
               if (user != null)
               {
                   var code = UserManager.GenerateChangePhoneNumberToken(
                                                                 user.Id, user.PhoneNumber);
                   UserManager.SendEmail(user.Id,
                                "Confirm your account",
                                                        "Your security code is: " + code);
                   return Ok(new { success = true, PhoneNumber = user.PhoneNumber, UserId = user.Id, message = C.RESENDVERIFICATIONCODEEMAILSUCCESS });
               }
           }
           else
           {
               return Ok(new { success = true, message = C.RESENDVERIFICATIONCODEEMAILSUCCESS });
           }
           return Ok(new { success = false, message = C.TRYAGAIN });
       }
       catch (Exception e)
       {
           LogError(e.Message, e);
           throw;
       }
   }

我们在生成安全代码和验证它时没有问题。我们面临的唯一问题是GenerateChangePhoneNumberToken方法会生成重复的代码。

Click one - Security Code : 123456 User ID : 1 

Click two - Security Code : 123456 User ID : 1 

一分钟后,它会生成不同的代码

Click three Security Code : 123457 User ID : 1 

因此,如果用户不断点击它,则会生成重复的安全码。如何防止这个问题?请帮忙......

1 个答案:

答案 0 :(得分:1)

这是设计的。用于确认电话的安全令牌取决于// Remove it curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($data_string)) ); 用户记录,电话号码和时间。鉴于电话号码和安全标记未更改,您将每3分钟获得一次新代码。

请参阅source code,方法SecurityStamp。甚至有评论public static int GenerateCode(SecurityToken securityToken, string modifier = null)
如果你深入研究代码,你会得到或多或少的代码片段:

// Allow a variance of no greater than 90 seconds in either direction

时间步长每3分钟才会改变一次。

如果生成多个相同的确认码是一个问题,我建议您更改UI以防止这种情况 - 一旦发送代码,禁用或删除要求此操作的按钮。从讨论中我了解到这是通过ajax请求在客户端完成的 - 它不应该是一个主要问题。