隐藏使用CreatedAtRoute显示的用户密码字段

时间:2015-04-08 15:45:53

标签: c# asp.net entity-framework asp.net-web-api

我正在构建一个ASP.NET Web API,我目前正在实现非常基本的用户帐户。我有User模型,其中只包含EmailPassword字段,我有一个UserController类,其操作如下:

// POST: api/Users
[ResponseType(typeof(User))]
public IHttpActionResult PostUser(User user)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    db.Users.Add(user);
    db.SaveChanges();

    return CreatedAtRoute("DefaultApi", new { id = user.Id }, user);
}

一切都很完美,除非我POST /api/Users我在响应正文中发回了密码字段:

{
    "Id":2,
    "Email":"dummy@test.com",
    "Password":"$2a$12$jTACgOlm2eO/OYcV5wrDnO2dmsnbWVnsCRzX1WfQKGsY4sYvh16gm"
}

如何确保敏感字段(如用户密码)永远不会在响应中输出?我更喜欢在模型级别上执行它的方法,这样我就不会忘记在控制器中实现它。

3 个答案:

答案 0 :(得分:3)

一种选择是在客户端和服务器之间进行通信时始终使用Data Transfer Object (DTO)。来自Web Api团队的this article给出的示例与您的问题非常相似。

我会创建一个UserDTO,它不会包含任何我想要在我的客户端和服务器之间传输的敏感数据。
这就是大多数API工作的方式,例如,Facebook通过this API call传递的用户不是来自其域的用户,而是用户的表示,只需要所需的信息。

使用DTO,您可以精确控制传输的内容,降低数据大小并防止安全信息泄露。

更新:如果你走这条路,你可能想要使用AutoMapper,它会减少你必须做的对象到对象的数量相当< /强>

答案 1 :(得分:1)

删除创建单独模型所需的一些值太多了,最好在返回之前清理数据,比如说

db.SaveChanges();

user.Password = String.Empty;
user.anyproperty = null;
return CreatedAtRoute("DefaultApi", new { id = user.Id }, user);

答案 2 :(得分:1)

约翰,

CreatedAtRoute方法用于返回新创建的资源的URI。例如,如果您要创建新产品,则可能会看到返回为api / products / 1234。该方法还将返回您提供的序列化对象作为第三个参数。该方法不知道您要返回的对象的性质,因此它不会将任何字段识别为敏感字段。

在您的情况下,您可以从用户对象中清除密码字段,或者返回不包含此字段的完全不同的对象。您不必被迫返回刚刚创建的同一对象。

最诚挚的问候, 丹尼尔