【问题标题】:Risks of using OData and IQueryable使用 OData 和 IQueryable 的风险
【发布时间】:2013-03-23 15:39:28
【问题描述】:

我看过很多关于制作 SPA(单页应用程序)的教程,其中许多使用外部库(例如轻柔和 jaydatajs)来获得自动化的数据服务层。

这些库希望我公开一个它们可以查询的 IQueryable 对象。

我的问题是,从服务器公开 IQueryable 有什么风险?我想知道使用这些 js 库创建这个快捷方式是否值得,或者我应该在服务器中公开我自己的函数并在客户端自己实现数据服务。

问题是,在公开 Iqueryable 时,我可以使用例如轻量级的js,使用类似 linq 的语法创建过滤和分页查询。如果我不使用它,我将不得不在服务器中实现这些用于过滤和分页的功能。并在 javascript 中实现对它们的调用。

我希望我很清楚:-)

【问题讨论】:

    标签: javascript linq odata iqueryable breeze


    【解决方案1】:

    在公开 IQueryable 时我会尝试做一件事...确保您不公开 EF 样式对象,始终确保您有某种可以控制的位于顶部的视图模型。

    举个例子,假设你的数据库有 User 和 UserSecrets

    public class User
    {
        public long UserId { get; set; }
        public string Name { get; set; }
        public virtual ICollection<UserSecret> UserSecrets { get; set; }
    }
    
    public class UserSecret
    {
        public long UserSecretId { get; set; }
        public long UserId { get; set; }
        public string Secret { get; set; }
    }
    

    如果您公开IQueryable&lt;User&gt;,您也可以轻松提取 UserSecrets

    www.blah.com/users?$expand=UserSecrets
    

    改为公开UserViewModel 或类似的东西

    public class UserViewModel
    {
         public string Name { get; set; }
    } 
    

    您可以通过以下方式公开IQueryable&lt;UserViewModel&gt;

    return dbContext.Users.Select(u => new UserViewModel { Name = u.Name })
    

    最棒的是这仍然是IQueryable - 你仍然可以过滤等,它仍然会在数据库级别执行,但是你可以控制可以提取哪些数据(在这种情况下UserSecret 不是更容易访问)。

    当然,您也可以应用自己的过滤器,这样您就可以避免用户无法访问他们不允许的数据:

    return dbContext.Users.Where(u => ...).Select(u => new UserViewModel { Name = u.Name })
    

    【讨论】:

    • 好的,似乎是一个很好的解决方案,所以你的意思是,我应该只公开这些实体的投影,而不是公开数据库实体。
    • 是的,如果需要,还可以预先过滤您的查询
    • 此解决方案无法处理更复杂的问题,即有些用户可以看到用户机密,有些则不能。
    【解决方案2】:

    可以看出,您创建了 DTO 对象以投影实体对象,并尝试在此 DTO 上制作基本属性。此操作将使我们保护从数据库公开的我们自己的信息,并避免将一些秘密信息从服务端泄露到客户端。

    【讨论】:

      猜你喜欢
      • 2012-07-26
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      相关资源
      最近更新 更多