public async Task <bool> VerifyRegistrationPhoneNumber([FromBody] VerifyPhoneNumberModel model)
        {
            if (model == null || !ModelState.IsValid)
            {
                throw new CustomException(Errors.INVALID_REQUEST, Errors.INVALID_REQUEST_MSG);
            }

            await _verificationService.VerifyRegistrationPhoneNumberAsync(model.PhoneNumber, model.PIN);

            return(true);
        }
예제 #2
0
        public async Task<IActionResult> ConfirmPhoneNumber(VerifyPhoneNumberModel model)
        {
            if (!ModelState.IsValid)
            {
                ModelState.Clear();
                return View();
            }

            #region Validate token data type & captcha

            if (!int.TryParse(model.Token, out _))
            {
                ModelState.AddModelError(string.Empty, "Token must be a number.");
                return View();
            }

            if (!await _captcha.IsCaptchaValidAsync())
            {
                ModelState.AddModelError(_captcha.CaptchaValidationError().Key, _captcha.CaptchaValidationError().Value);
                return View();
            }

            #endregion Validate token data type & captcha

            ApplicationUser user = await _accountRepository.GetUserFromContextAsync(User);

            #region Validating password & ensuring token validity

            if (!await _accountRepository.IsPasswordValidAsync(user, model.Password))
            {
                _captcha.DeleteCaptchaCookie();
                ModelState.AddModelError(string.Empty, "Incorrect Password.");
                return View();
            }

            if ((await _accountRepository.ConfirmPhoneAsync(user, model.Token)).Succeeded)
            {
                model.IsCompleted = true;
                user.UnverifiedNewPhone = string.Empty;
                await _captcha.CacheNewCaptchaValidateAsync();
                await _accountRepository.UpdateUserAsync(user);
                _logger.LogInformation($"{user.Id} ({user.UserName}) - Confirmed phone number successfully.");
                return View(model);
            }

            #endregion Validating password & ensuring token validity

            ModelState.AddModelError(string.Empty, "Invalid or Expired Token.");
            return View(model);
        }
예제 #3
0
        public async Task <ActionResult> VerifyPhoneNumber(VerifyPhoneNumberModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }
            var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code);

            if (result.Succeeded)
            {
                var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

                if (user != null)
                {
                    await SignInManager.SignInAsync(user, isPersistent : false, rememberBrowser : false);
                }
                return(RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess }));
            }
            // Это сообщение означает наличие ошибки; повторное отображение формы
            ModelState.AddModelError("", "Не удалось проверить телефон");
            return(View(model));
        }
예제 #4
0
        public async Task <ActionResult> VerifyPhoneNumber([FromForm] VerifyPhoneNumberModel formModel)
        {
            TryValidateModel(formModel);
            if (!ModelState.IsValid)
            {
                return(View("customers/verify_phone_number", WorkContext));
            }

            var result = await _signInManager.UserManager.ChangePhoneNumberAsync(WorkContext.CurrentUser, formModel.PhoneNumber, formModel.Code);

            if (result.Succeeded)
            {
                await _signInManager.SignInAsync(WorkContext.CurrentUser, isPersistent : false);

                return(StoreFrontRedirect("~/account"));
            }

            // If we got this far, something failed
            WorkContext.Form.Errors.Add(SecurityErrorDescriber.PhoneNumberVerificationFailed());
            WorkContext.Form = Form.FromObject(formModel);

            return(View("customers/verify_phone_number", WorkContext));
        }
예제 #5
0
        public async Task <IActionResult> VerifyPhoneNumber(VerifyPhoneNumberModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }
            var user = await GetCurrentUserAsync();

            if (user != null)
            {
                var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);

                if (result.Succeeded)
                {
                    await _signInManager.SignInAsync(user, isPersistent : false);

                    return(RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess }));
                }
            }
            // If we got this far, something failed, redisplay the form
            ModelState.AddModelError(string.Empty, "Failed to verify phone number");
            return(View(model));
        }
예제 #6
0
        public async Task <ApiResult <string> > VerifyPhoneNumber([FromBody] VerifyPhoneNumberModel value)
        {
            if (!ModelState.IsValid)
            {
                return(new ApiResult <string>(l, BasicControllerCodes.UnprocessableEntity,
                                              ModelErrors()));
            }

            #region 发送计数、验证是否已经达到上限
            var dailyLimitKey = RedisKeys.Limit_24Hour_Verify_Phone + value.PhoneNumber;

            var _dailyLimit = await redis.Get(dailyLimitKey);

            if (!string.IsNullOrWhiteSpace(_dailyLimit))
            {
                var dailyLimit = int.Parse(_dailyLimit);

                if (dailyLimit > RedisKeys.Limit_24Hour_Verify_MAX_Phone)
                {
                    return(new ApiResult <string>(l, UserControllerCodes.VerifyPhoneNumber.CallLimited));
                }
            }
            else
            {
                await redis.Set(dailyLimitKey, "0", TimeSpan.FromHours(24));
            }
            #endregion

            #region 验证发送间隔时间是否过快
            //两次发送间隔必须大于指定秒数
            var _lastTimeKey = RedisKeys.LastTime_SendCode_Phone + value.PhoneNumber;

            var lastTimeString = await redis.Get(_lastTimeKey);

            if (!string.IsNullOrWhiteSpace(lastTimeString))
            {
                var lastTime = long.Parse(lastTimeString);

                var now = DateTime.UtcNow.AddHours(8).Ticks;

                var usedTime = (now - lastTime) / 10000000;

                if (usedTime < RedisKeys.MinimumTime_SendCode_Phone)
                {
                    return(new ApiResult <string>(l, UserControllerCodes.VerifyPhoneNumber.TooManyRequests, string.Empty,
                                                  RedisKeys.MinimumTime_SendCode_Phone - usedTime));
                }
            }
            #endregion

            #region 发送验证码
            var verifyCode = random.Next(1111, 9999).ToString();
            var smsVars    = JsonConvert.SerializeObject(new { code = verifyCode });
            await sms.SendSmsWithRetryAsync(smsVars, value.PhoneNumber, "9900", 3);

            #endregion

            var verifyCodeKey = RedisKeys.VerifyCode_Phone + value.PhoneNumber + ":" + verifyCode;

            // 记录验证码,用于提交报名接口校验
            await redis.Set(verifyCodeKey, string.Empty, TimeSpan.FromSeconds(RedisKeys.VerifyCode_Expire_Phone));

            // 记录发送验证码的时间,用于下次发送验证码校验间隔时间
            await redis.Set(_lastTimeKey, DateTime.UtcNow.AddHours(8).Ticks.ToString(), null);

            // 叠加发送次数
            await redis.Increment(dailyLimitKey);

            return(new ApiResult <string>());
        }