设计:当管理员和用户在同一浏览器的不同选项卡上登录时使用 `admin_signed_in?` 的逻辑

Posted

技术标签:

【中文标题】设计:当管理员和用户在同一浏览器的不同选项卡上登录时使用 `admin_signed_in?` 的逻辑【英文标题】:Devise: logic using `admin_signed_in?` when Admin & User logged in on separate tabs in same browser 【发布时间】:2014-07-23 20:26:09 【问题描述】:

在我的 Rails 3.2 应用程序中有两个设计模型:用户和管理员。我有一个评论部分表单,两者都可以用来在帖子上制作 cmets。但是,我在 *_signed_in? 中包含了条件逻辑?由 Devise 提供的帮助程序,以便为管理员显示一个复选框,允许他们使他们的评论仅对其他管理员可见。表单复选框代码:

- if admin_signed_in?
  .pull-right
    = label_tag :internal, "Private"
    = f.check_box :internal

这不是一个大问题,因为它不应该在生产中发生,但在开发和登台时,我注意到如果某人(测试人员等)在同一浏览器的不同选项卡中以管理员和用户的身份登录,我的表单的逻辑不起作用,因为(我猜?)这两个选项卡使用相同的 cookie/会话信息/其他。该复选框显示在用户表单上,因为管理员已在另一个选项卡上登录。如果使用两种不同的浏览器,它就可以正常工作。

有没有办法避免这种情况?

【问题讨论】:

不这么认为。如果您以自己的帐户和测试用户帐户的身份登录 facebook,这是一种类似的行为。它取代了您现有的会话。可能可以为管理员和普通用户使用两个不同的 cookie,但这不是一个干净的解决方案。如果他们想同时以不同用户的身份登录,最好使用多个浏览器。 【参考方案1】:

您可能需要查找或创建一个变量,该变量可用于确定您是否在网站的管理部分。一种俗气的方法是在您的管理控制器中放置一个前置过滤器,该过滤器设置一个实例变量(例如@admin_site = true),然后更新您的部分:

- if admin_signed_in? && @admin_site
  .pull-right
    = label_tag :internal, "Private"
    = f.check_box :internal

但是,某些人(例如 Sandi Metz)认为增加发送到视图的实例变量是不好的做法。此外,最好将参数作为局部变量显式传递给局部变量,而不是依赖实例变量。 (这有助于提高可读性并使其更易于共享)。

外观模式在这里可以提供帮助。

http://robots.thoughtbot.com/sandi-metz-rules-for-developers

编辑:

由于使用外观,我倾向于拒绝一般的助手,但你可能会做这样的事情:

#app/helpers/application_helper.rb
module ApplicationHelper

  def show_internal?
    request[:controller].in? ['admin']
  end

  ...

假设您的管理操作都在一个名为“admin_controller”的控制器中。

如果您有很多管理控制器,您可以通过添加到数组中来添加更多管理控制器:

  request[:controller].in? ['user_admin', 'product_admin']

【讨论】:

另外,不要以为这种事情不会在生产中发生。 :) 谢谢!这是正确的。现在我只需要使用一个管理员控制器,通过另一个 SO 问题,我发现我可以在带有 params[:controller] 的视图中访问当前控制器,所以我只使用了这个带有 params[:controller] == "admin/jobs" 的助手。

以上是关于设计:当管理员和用户在同一浏览器的不同选项卡上登录时使用 `admin_signed_in?` 的逻辑的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止用户从同一帐户但不同的选项卡登录两次

页面刷新和多个选项卡上的 Vuex 状态

如何在 NUnit 测试框架上使用 selenium C# 在新的 Chrome 选项卡上打开 url

javascript 当用户失去对站点的焦点时,切换浏览器选项卡上的文本(标题)(切换选项卡)

在同一选项卡上加载另一个页面,在地址栏上保持以前的 url

我希望我的 php 表单提交数据并在同一页面但不同的选项卡上重定向