Риски использования OData и IQueryable

Я видел много руководств по созданию SPA (одностраничных приложений), и многие из них используют внешнюю библиотеку, такую ​​как breezejs и jaydatajs, чтобы получить автоматизированный слой службы данных.

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

Мой вопрос: каковы риски разоблачения IQueryable с сервера? Я хочу знать, стоит ли делать этот ярлык с этими js-библиотеками, или я должен выставлять свои собственные функции на сервере и самостоятельно реализовывать службу данных в клиенте.

Дело в том, что при раскрытии Iqueryable я могу использовать breezejs, например, для создания запросов для фильтрации и пейджинга с синтаксисом, подобным linq. Если я не буду его использовать, мне придется реализовать эти функции для фильтрации и пейджинга на сервере. и реализовать вызовы к ним в javascript.

Надеюсь понятно выразился :-)


person DorR    schedule 02.04.2013    source источник


Ответы (2)


Есть одна вещь, которую я пытаюсь сделать при раскрытии 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<User>, вы также можете легко извлечь UserSecrets.

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

Вместо этого выставьте UserViewModel или что-то подобное

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

Вы можете разоблачить IQueryable<UserViewModel> следующим образом:

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

Самое замечательное, что это по-прежнему IQueryable — вы по-прежнему можете фильтровать и т. д., и он по-прежнему будет выполняться на уровне базы данных, но вы точно контролируете, какие данные можно извлечь (в этом случае UserSecret больше не доступен).

Конечно, вы также можете применять свои собственные фильтры, чтобы пользователи не могли получить доступ к данным, которым они не разрешены:

return dbContext.Users.Where(u => ...).Select(u => new UserViewModel { Name = u.Name })
person Felix    schedule 02.04.2013
comment
ОК, похоже на хорошее решение. Итак, вы говорите, что вместо того, чтобы выставлять сущности БД, я должен выставлять только проекции этих сущностей. - person DorR; 02.04.2013
comment
Да, и предварительно отфильтруйте ваши запросы, если это необходимо. - person Felix; 02.04.2013
comment
Это решение не решает более сложную проблему, когда некоторые пользователи могут видеть пользовательские секреты, а некоторые нет. - person Kurren; 13.11.2015

Видно, что вы создаете объект DTO для проекции объекта сущности и пытаетесь создать основные свойства этого DTO. Это действие защитит нашу собственную информацию, которая раскрывается из базы данных, и предотвратит передачу некоторой секретной информации со стороны службы клиенту.

person thangchung    schedule 04.04.2013