我只是在用户点击浏览器中的按钮时才尝试在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
并伪造用户会话以访问我的应用程序的受保护区域。是否有更安全的方式开始会议?
答案 0 :(得分:0)
我找到了两个可能解决这个问题的方法。
选项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创建的会话范围。这可以通过向您要创建的会话添加另一个级别来轻松实现,即 - 为会话提供父级&gt;孩子的关系。看看:
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]
的会话,这个会话实际上没用。