生产模式下的append_before_filter

发布于 2024-11-03 19:55:42 字数 750 浏览 0 评论 0原文

我有一个控制器,它根据登录用户在两个不同的“上下文”中运行(基本上,用户可以在自己的帐户上执行 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城月光淡如水﹏ 2024-11-10 19:55:42

我的猜测是,由于开发会在每个页面点击时重新加载类,因此append_before_filter调用仅适用于该页面点击,但由于生产会缓存类,因此调用append_before_filter会将其附加到控制器的后续使用中。这是一个有效的假设吗?如果是这样,我该怎么办?

你在这里的说法是完全正确的。在生产中,您不能像这样更改类上的过滤器链,因为类是持久的,因此,如果您更改过滤器链,那么现在会影响该控制器类从该点开始处理的每个请求。我只会使用普通的 before 过滤器方法,该方法根据 user_context? 调用其他方法之一,如下所示:

before_filter :ensure_logged_in, :only => [:show, :edit, :update]

def ensure_logged_in
  if user_context?
    return authorize_user
  else
    return authorize_admin
  end
end

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?

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:

before_filter :ensure_logged_in, :only => [:show, :edit, :update]

def ensure_logged_in
  if user_context?
    return authorize_user
  else
    return authorize_admin
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文