Редактировать пользователя удаляет пароль - ASP.NET MVC - PullRequest
0 голосов
/ 09 июня 2018

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

Модель

public class User : IdentityUser
{        
    [Display(Name = "First name")]
    public String FirstName { get; set; }

    [Display(Name = "Last name")]
    public string LastName { get; set; }

    public string Email{ get; set; }
 }

Обратите внимание, чтоПользовательский класс происходит от IdentityUser, который содержит переменные пароля.

Редактирование в контроллере

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "FirstName,LastName,Email,PhoneNumber")] User user)
    {
        if (ModelState.IsValid)
        {
            db.Entry(user).State = System.Data.Entity.EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(user);
    }

Просмотр для редактирования

<div class="form-horizontal">
<h4>User</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)

<div class="form-group">
    @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.PhoneNumber, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.PhoneNumber, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.PhoneNumber, "", new { @class = "text-danger" })
    </div>
</div>


    <div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Save" class="btn btn-default" />
    </div>
</div>

}

Насколько я понимаю, параметр Bind в методе Edit либо вносит белый, либо черный список переменных для редактирования.Поэтому по этой причине я удалил все значения, которые не должны редактироваться пользователем в Bind.

1 Ответ

0 голосов
/ 09 июня 2018

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

@Html.HiddenFor(model => model.Id)

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

Надеюсь, вы понимаете, как это плохо:)

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

db.Entry(user).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();

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

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

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

var existingUser = db.Users.Single(u => u.Id == currentUserId);
existingUser.FirstName = user.FirstName;
existingUser.LastName = user.LastName;
// etc.
db.SaveChanges();

Обратите внимание, что я использовал неопределенную переменную с именем currentUserId. Не используйте model.Id, потому что опять же это позволяет пользователю указать, какого другого пользователя он хочет редактировать.Определение текущего идентификатора пользователя по текущему сеансу, вошедшему в систему, а не по тому, что они отправляют в формеОднако вы в настоящее время идентифицируете своих пользователей.(User.Identity?)

Короче ...

  • Позволять пользователю видеть / редактировать только то, что ему разрешено
  • Подтвердить в действии сохранениячто пользователю разрешено редактировать эти данные ( никогда не предполагает, что им должно быть разрешено просто потому, что они ранее открыли страницу)
  • обновляют только значения, предназначенные для обновления в этой операции,не просто оптом замените целую запись конфиденциальных данных
...