Какой лучший способ проверить текущий пароль? - PullRequest
0 голосов
/ 17 октября 2018

Я создал форму, где пользователь может обновить свою учетную запись данных.В этой форме пользователь также может изменить пароль учетной записи, перед этим я спрашиваю у него текущий пароль, это поле:

<div class="form-group">
    <label>Current Password</label>
    <input class="form-control" id="oldPassword"
            asp-for="@Model.ExistingPassword" type="password" />
    <div class="invalid-feedback"></div>
</div>

, поскольку вы видите, что ввод oldPassword ограничиваетсвойство ExistingPassword, которое является частью ViewModel этого View и имеет следующее объявление:

[Required, MinLength(6), MaxLength(50), DataType(DataType.Password)]
public string ExistingPassword { get; set; }

при отправке формы я вызываю следующую ajax функцию:

$.post(url, user, function (response) {

    //Some stuff

}).done(function (response) {
        alert("Updated executed");
    }).fail(function (jqXHR, textStatus, errorThrown) {
        alert("Error happened!");
});

параметр функции принимается формой, в частности:

  • url: $(this).attr('action');
  • user: $(this).serialize();

действие формы вызовет следующий контроллер: User\UpdateUser.Внутри метода UpdateUser я выполняю следующую проверку:

public async Task<UserProfileViewModel> UpdateUserAsync(UserProfileViewModel updatedUser)
{
    if (!await _userManager.CheckPasswordAsync(originalUser, updatedUser.ExistingPassword))
       throw new Exception("Invalid password");

по существу, проверка условия, если текущий пароль правильный, если нет, то будет сгенерировано исключение.

Теперь,у меня такой вопрос: как я могу узнать, какой тип исключения сгенерировал метод?

Мне нужно знать, какой тип исключения сгенерировал метод UpdateUser, потому что в методе есть разные исключения.

Предположим, возникли исключения Invalid Password, мне нужно отобразить сообщение внутри invalid-feedback div, рядом с oldPassword, чтобы пользователь знал, почему обновление не удалось.

Спасибозаранее за любую помощь.

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Посмотрите на метод UserManager ChangePassword .

Вы можете привязать UserManager к использованию DependencyInjection следующим образом (в Startup.cs)

public async void Configure(IApplicationBuilder app, IHostingEnvironment env)
      {
           ...

            app.UseAuthentication();
            app.UseMvc();

            var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
            using (var scope = scopeFactory.CreateScope())
            {
                UserManager<User> userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
            }

        }

Изатем в конструкторе вашего контроллера

    private readonly UserManager<User> _userManager;

    public AccountController(UserManager<User> userManager)
    {
        _userManager = userManager;
    }

И, наконец, ваша конечная точка:

    [HttpPost("ChangePassword")]
    public async Task<IActionResult> ChangePassword([FromBody]ChangePasswordRequest changePasswordParams)
    {
        if (changePasswordParams == null)
            return BadRequest($"{nameof(changePasswordParams)} must not be null!");

        if (string.IsNullOrWhiteSpace(changePasswordParams.OldPassword) || string.IsNullOrWhiteSpace(changePasswordParams.NewPassword))
            return BadRequest("old and new passwords have to be provided, but they both are empty.");

        var userId = User.Claims.FirstOrDefault(c => c.Type == "id")?.Value;
        var user = await _userManager.FindByIdAsync(userId);
        var result = await _userManager.ChangePasswordAsync(user, changePasswordParams.OldPassword, changePasswordParams.NewPassword);

        if (result.Succeeded)
            return NoContent();

        return BadRequest(result.Errors);
    }

, после этого вы можете обработать ошибки в операторе switch.

0 голосов
/ 18 октября 2018

Использование исключений для обработанных ошибок не рекомендуется, так как они обычно заканчиваются внутренней ошибкой сервера, и на самом деле это выходит за рамки его цели.

Наилучшим подходом будет отправка BadRequest, как указано @maerlin.

Однако, если вы настаиваете на использовании Исключений в вашем приложении или ваше приложение спроектировано таким образом.Я предлагаю вам наследовать новый класс CustomApplcationException от ApplicationException, а затем наследовать UpdateUserException и против класса CustomApplicationException.После этого я предлагаю вам обработать ваши исключения в ErrorHandlingMiddleware и вернуть хотя бы HandledExceptions с кодом состояния BadRequest (400).

Пример кода будет

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILoggerManager _logger;

    public ExceptionMiddleware(RequestDelegate next, ILoggerManager logger)
    {
        _logger = logger;
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
        }
        catch (CustomApplicationException cae)
        { 
            await HandleCustomExceptionAsync(httpContext, cae);
        }
        catch (Exception ex)
        {
            _logger.LogError($"Something went wrong: {ex}");
            await HandleExceptionAsync(httpContext, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

        return context.Response.WriteAsync(new ErrorDetails()
        {
            StatusCode = context.Response.StatusCode,
            Message = "Internal Server Error from the custom middleware."
        }.ToString());
    }

    private static Task HandleCustomExceptionAsync(HttpContext context, Exception exception)
    {
        context.Response.StatusCode = 400;

        return context.Response.WriteAsync(new ErrorDetails()
        {
            StatusCode = context.Response.StatusCode,
            Message = exception.Message
        }.ToString());
    }
}

, тогда вам нужно зарегистрироватьПромежуточное программное обеспечение в вашем Startup.cs

 app.UseMiddleware<ExceptionMiddleware>();

. Для получения дополнительной информации см. https://code -maze.com / global-error-processing-aspnetcore / и http://www.talkingdotnet.com/global-exception-handling-in-aspnet-core-webapi/.

0 голосов
/ 17 октября 2018

Обычно я рекомендую не использовать исключение, кроме как в реальных обстоятельствах исключения, но, учитывая то, как вы это спроектировали, у вас есть несколько вариантов.

Я бы предложил создать специальное «UpdateUserException», которое вы можете выдать, которое будет включать дополнительную информацию, которая может быть предоставлена ​​перечислением или просто строкой.

public class UpdateUserException : Exception {
    public UpdateUserError ErrorCondition;

    public UpdateUserException(UpdateUserError error, string message)
    {
        ErrorCondition = error;
        Message = message;
    }
}

тогда вы бы бросилиэто

throw new UpdateUserException(UpdateUserError.BadPassword, "Invalid Password");

тогда вы поймали бы это

try {}
catch (UpdateUserException e)
{
    if (e.ErrorCondition == UpdateUserException.BadPassword)
    {
        // handle your exception.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...