【问题标题】:Best way to start a session dynamically from a URL从 URL 动态启动会话的最佳方式
【发布时间】:2013-12-01 06:16:53
【问题描述】:

我仅在用户单击浏览器中的按钮时才尝试在 Rails 中创建会话。使用 jQuery 解决此问题的最佳方法是什么?

这样的实际用途可能是:

  • 防止警报在关闭后再次显示。
  • 记住不同阶段的用户信息。
  • 在操作完成后保存基本的一次性设置。

我想出了这个:

HTML:

<button id="startSession">Start a Session!</button>  

jQuery:

$("#startSession").click(function() {
  $.ajax({
    url: "/sessions-manager?add=funkysession"
  });
});

然后控制器看起来像:

get "/sessions-manager" do
  name = params[:add].to_sym
  session[name] = true  #=> session[:funkysession] = true

  # A session named "funkysession" has now been started
end

但是,我觉得这种方式很容易被利用。例如,人们可以手动输入/sessions-manager?add=user 并伪造一个用户会话来访问我的应用程序的受保护区域。有没有更安全的方法来开始会话?

【问题讨论】:

    标签: jquery ruby-on-rails security session sinatra


    【解决方案1】:

    我为这个问题找到了两种可能的解决方案。

    选项 1:在 AJAX 请求中发送自定义标头

    这背后的想法是设置一个自定义 HTTP 标头与实际的 AJAX 请求一起发送,然后将在控制器中进行检查。这意味着人们无法在 Web 浏览器的 URL 栏中手动成功地与 /sessions-manager 路由交互。可以使用 jQuery 轻松设置自定义标题:

    $("#startSession").click(function() {
      $.ajax({
        url: "/sessions-manager?add=showpassword",
        beforeSend: function(xhr){xhr.setRequestHeader('foo', 'bar');}
      });
    });
    

    现在只需检查您的自定义标头是否存在于控制器中:

    get "/sessions-manager" do
      if env["foo"] == "bar"
        // Add session
      else
        halt 401 // Authentication required error
      end
    end
    

    关于这种方法的附注:虽然这肯定是保护/sessions-manager 路由的有效方法,但它仍然可能受到损害。知道自己在做什么的人可以使用开发人员工具伪造 HTTP 标头,因此选项 2 可能适合您。尽管如此,这仍然是一个很好的策略,可以作为额外的保护层来实施,只是知道它的限制。

    选项 2(首选):多个会话级别

    比特币策划者 Sam Foley 引起我注意的一个更有效的解决方案是限制可以通过/sessions-manager URL 创建的会话范围。这可以通过向您要创建的会话添加另一个级别来轻松实现,即 - 为会话提供父 > 子关系。看看吧:

    get "/sessions-manager" do
      session[:userprefs] ||= {} // Set parent session as empty hash
      name = params[:add].to_sym
      session[:userprefs][:name] = true
    end
    

    好多了。现在我们可以在应用程序的任何位置(视图或控制器)访问此会话:

    if session[:userprefs][:showpassword] 
      "Password is blah"
    end 
    

    更重要的是,人们无法伪造现有会话。例如,试图伪造用户会话的人现在将创建一个名为 [:userprefs][:user] 的会话,这实际上是无用的。

    【讨论】:

    • 所以......这并没有真正做任何事情。您只是以一种非常典型的方式使用现有的 Rails 会话机制。这不完全是新闻价值。
    • 嗯,不...问题是询问通过 URL 启动会话的最佳方式,而不会使应用程序容易受到攻击(例如 - 有人启动虚假使用会话)。抱歉,我的解决方案使用“现有的 Rails 会话机制”。也许我下次应该使用 PHP 的 $_SESSION[""] 功能重写我的答案?
    • 这并不重要,在任何一种情况下,您所做的只是在现有会话机制中存储一个值,以一种完全普通的方式,这就是所说的机制的明确用途。对不起,我真的不明白你想要做什么,或者为什么它很新颖。
    • 在发布此问题时,我不知道能够堆叠会话哈希。我把它作为我的 jQuery 解决方案的替代方案,因为它更安全,而且,快速的 Google 搜索表明,也没有多少 Rails 开发人员知道它。
    猜你喜欢
    • 2011-08-17
    • 2010-09-08
    • 2010-11-03
    • 2010-10-22
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    相关资源
    最近更新 更多