【问题标题】:sensitive entities敏感实体
【发布时间】:2012-06-10 15:04:56
【问题描述】:

我想允许我的用户更新他们的帐户详细信息。为简化起见,假设帐户模型由IDNameSurnameUsernamePassword 组成,并且我只希望用户能够更改NameSurname .问题是如果我将帐户模型传递给视图,我需要为IDUsernamePassword 创建隐藏字段。现在即使我可以加密这些数据,将密码放在视图中也不安全。

另一种方法是创建一个 EditAccount 视图模型,其中仅包含 IDNameSurname,但是在控制器操作中,我需要再次搜索正在修改的用户和在保存之前手动分配新的NameSurname,这种方法不是特别简洁。您对这种情况有什么建议吗?

【问题讨论】:

    标签: asp.net-mvc-3 model-view-controller editing


    【解决方案1】:

    绝对创建一个不包含Password 的单独 ViewModel 并将其发送到编辑视图。为特定需求使用特定的 ViewModel 是完全正常的。这就是 ViewModel 的用途。它们重量轻且可重复使用。它们旨在重塑您的实体数据以满足 UI 的需求,以仅包含您需要的内容。这是首选方法,因为它适用于 MVC 模式,而不是反对它。

    如果需要,您可以创建一个继承层次结构,例如具有一个非敏感数据 ViewModel 和一个用于继承非敏感数据的敏感数据,以满足更改用户密码的需要。如:

    使用它来编辑用户:

    public class UserEditViewModel {
    
        public int ID { get; set; }
    
        [Required]
        public string Name { get; set; }
    
        public string Surname { get; set; }
    }
    

    当您需要 User 信息和 Password 时使用它。当您希望允许用户编辑他们的密码时使用此模型

    public class SensitiveUserViewModel : UserEditViewModel {
    
        [Required]
        public string Username { get; set; }
    
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Current Password")]
        public string OldPassword { get; set; }
    
        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New Password")]
        public string NewPassword { get; set; }
    
        [DataType(DataType.Password)]
        [Display(Name = "Confirm New Password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match")]
        public string ConfirmPassword { get; set; }
    }
    

    您进行编辑的视图将具有这些操作。这样编辑不敏感的用户信息就只有你需要的数据,没有安全问题。

    public ActionResult EditUser(int ID) {
        // get User by ID
        var model = new UserEditViewModel();
        // map your entity fields to ViewModel
        return View(model);
    }
    
    public ActionResult EditUser(UserEditViewModel model) {
        if(ModelState.IsValid) {
            // save user edits
        }
        return View(model);
    }
    

    您应该使用单独的视图来允许用户编辑密码信息。这样您就可以使用SensitiveUserViewModel,这样您就拥有了所有数据、敏感和非敏感属性。这样可以保持一切干净,因为您的所有属性都在一个位置,并且仅用于更改 Password,而不是编辑 NameSurname

    public ActionResult ChangePassword(int ID) {
        // get user by ID
        var model = new SensitiveUserViewModel();
        // map your entity to ViewModel
        return View(model);
    }
    
    [HttpPost]
    public ActionResult ChangePassword(SensitiveUserViewModel model) {
        if(ModelState.IsValid) {
            // save user password info
        }
        return View(model);
    }
    

    【讨论】:

    • 是的,这就是我对第二个选项的暗示。这是最合乎逻辑的方式,但是,有没有一种方法可以将视图模型的状态转移到模型,而不必单独分配每个属性。换句话说,在“保存用户信息”部分有一个替代写 model.PropertyName = viewModel.PropertyName。我问是因为如果你有很多属性,这将是不可维护的。你会考虑使用反射来完成这样的任务吗?
    • 反思,没有。这只是野兽的本性,但您可以使用 Automapper 为您处理所有这些。多年来,我一直在做手动分配,从来没有想过任何事情,因为这就是它的完成方式。但现在 Automapper 将为您完成所有这些工作。看看automapper.org
    猜你喜欢
    • 2019-01-12
    • 2014-01-12
    • 2011-08-11
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 2012-11-23
    • 2021-03-09
    • 2011-01-15
    相关资源
    最近更新 更多