我们正在构建一个使用数据库的Web应用程序。我们还使用对象关系映射器来访问数据库。 Web应用程序中授权的一个方面是用户可以访问URL引用的对象。 URL包含数据库中特定记录的唯一ID(例如主键)。请考虑以下示例。
假设我们有以下网址:http://app.local/question/edit/10。这意味着我们要使用PK 10编辑问题。现在,我们要验证登录的用户是否可以使用PK 10访问问题。这可以通过检索此问题,然后是调查然后是组,然后是所有用户来完成。如果任何用户与登录的用户相同,则登录的用户可以访问问题。
稍微概括一下;我们想通过已知的多对一或多对多关系检查来自另一条记录的记录是否可以到达。因此,如果存在多对一关系(例如调查和问题,那么我们应该检查用户是否可以从问题通过调查然后通过组。组具有多对多关系用户所以我们应该检查用户中是否有任何(并非所有)用户。
如果一个表有多个多对一关系,请说;我们可以将CSS 模板附加到调查,此模板也属于组然后我们必须检查如果可以从所有多对一关系(因此组和模板)访问用户。当然,对多个多对多关系也是如此。
是否有支持此行为的对象关系映射器?这种行为叫做什么,可能是可达性? Propel(对于PHP)是否支持此行为?我认为这种可达性可以通过以下两种方式中的任何一种来完成:
此外,ORM的这种行为应该支持嵌套集,因此如果组包含嵌套集行为,它还应该尝试通过组的父级访问用户
我认为这种行为不应仅限于授权;对象应该只是能够看到它们是否可以到达另一个对象。
请注意,我并不是指可达性的持久性:http://jpaobjects.sourceforge.net/m2-site/main/documentation/docbkx/html/user-guide/ch08s03.html。
或者......我只是认为这个授权是错误的,并且ORM有更好的方法吗?
答案 0 :(得分:1)
我过去使用Ruby on Rails中的嵌套资源(使用Active Record ORM)处理过这个问题。 URI不是http://app.local/question/10/edit,而是http://app.local/survey/5/questions/10/edit
在控制器中,您同时加载问题和调查。您可以通过将调查与经过身份验证的用户的组成员身份进行比较来检查授权。设计这种方法的一种方法是将此逻辑嵌入到User类中。例如,在控制器中,您有question
和survey
(并且ORM很好地理解了两者之间的关系,即question.survey
)。然后,您可以将访问权限检查为user.hasAccess?(question)
,这将是一种相对简单的编写方法。伪代码:
class User < ActiveRecord::Base
def hasAccess?(question)
return question.group.users.include?(self)
是的,这将在幕后产生多个查询,但ORM会完成工作。我是这样做的,因为你留下了坚实的架构和易于阅读的代码。在实际出现性能问题之前不要进行优化。