使用 CreatedAtRoute 隐藏用户密码字段

Hiding user password field from being displayed using CreatedAtRoute

我正在构建一个 ASP.NET 网站 API,我目前正在实施非常基本的用户帐户。我有一个 User 模型,它只包含 EmailPassword 字段,我有一个 UserController class 具有以下操作:

// 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":"a$jTACgOlm2eO/OYcV5wrDnO2dmsnbWVnsCRzX1WfQKGsY4sYvh16gm"
}

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

一种选择是始终使用来自网络的 Data Transfer Object (DTO) when communicating between a client and the server. The example given by this article Api 团队与您的问题非常相似。

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

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

更新:如果你走那条路,你可能会想要使用AutoMapper,它减少了你必须做的对象到对象映射的数量相当.

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

db.SaveChanges();

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

约翰,

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

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

此致, 丹尼尔