生产模式下的append_before_filter
我有一个控制器,它根据登录用户在两个不同的“上下文”中运行(基本上,用户可以在自己的帐户上执行 CRUD 操作,管理员用户可以 CRUD 所有用户帐户;上下文之间的操作是相同的但权限不同)。
为了促进这一点,我编写了一个 before 过滤器,它检查上下文并在过滤器之前附加正确的上下文特定权限:
def ensure_logged_in
if user_context?
self.class.append_before_filter :authorize_user
else
self.class.append_before_filter :authorize_admin
end
end
此外,仅在特定操作上调用 ensure_logged_in
:
before_filter :ensure_logged_in, :only => [:show, :edit, :update]
这在开发模式下工作得很好,但是一旦代码投入生产,我们就开始遇到奇怪的行为(即,用户被要求登录以执行不需要登录的操作;控制器中有几个打开视图操作)。
我的猜测是,由于开发会在每个页面点击时重新加载类,因此 append_before_filter
调用仅适用于该页面点击,但由于生产会缓存类,因此调用 append_before_filter
会将其附加到后续使用控制器。这是一个有效的假设吗?如果是这样,我该怎么办?
I have a controller that runs in two different "contexts" based on the logged in user (basically, a user can perform CRUD operations on their own account, and an admin user can CRUD all user accounts; the actions are the same between the contexts but the permissions are different).
In order to facilitate this, I wrote a before filter which checks the context and appends the correct context-specific permission before filter:
def ensure_logged_in
if user_context?
self.class.append_before_filter :authorize_user
else
self.class.append_before_filter :authorize_admin
end
end
Furthermore, ensure_logged_in
is only called on specific actions:
before_filter :ensure_logged_in, :only => [:show, :edit, :update]
This works perfectly fine in development mode, but once the code is in production we started experiencing weird behaviour (ie. users are being asked to log in for actions that a login should not be required; there are a couple open view actions in the controller).
My guess is that because development reloads classes each page hit, the append_before_filter
call only applies for that page hit, but because production caches classes, calling append_before_filter
appends it for subsequent uses of the controller. Is this a valid assumption? If so, what can I do instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你在这里的说法是完全正确的。在生产中,您不能像这样更改类上的过滤器链,因为类是持久的,因此,如果您更改过滤器链,那么现在会影响该控制器类从该点开始处理的每个请求。我只会使用普通的 before 过滤器方法,该方法根据
user_context?
调用其他方法之一,如下所示:Your statement here is exactly correct. In production you can't be changing the filter chain on the classes like that because classes are persistant, so if you change the filter chain, that now effects every request processed by that controller class from that point forward. I would just use a normal before filter method, that calls either one of the other ones based on
user_context?
something like this: