【问题标题】:How can I disable URL-encoding of cookies in Rails如何在 Rails 中禁用 cookie 的 URL 编码
【发布时间】:2017-01-20 08:50:56
【问题描述】:

我有一个 Rails 应用程序,它必须与一个非常旧的遗留应用程序共存。旧版应用程序会查找具有包含特定字符串的值的 cookie。不幸的是,遗留 cookie 中的字符通常包含斜杠。我遇到的问题是,当 Rails 应用程序写入 cookie 时,它​​首先进行 URL 编码,这会导致遗留应用程序中断,因为 cookie 值不正确。

我通过编辑文件cookie_performance_fix.rb(路径:./actionpack-1.13.5/lib/action_controller/cgi_ext/cookie_performance_fix.rb)在 Rails 1.13.5 中进行了此操作
为了让它工作,我更改了代码,如下所示:

def to_s
  buf = ""
  buf << @name << '='

  if @value.kind_of?(String)
    rails code. 
        #buf << CGI::escape(@value)
         buf << @value
  else
        #buf << @value.collect{|v| CGI::escape(v) }.join("&")
    buf << @value.collect{|v| (v) }.join("&")

  end

在我决定将 Rails 升级到 2.3.2 版本之前,这实际上运行良好
在 Rails 2.3.2 中,cookie_performance_fix.rb 文件不再存在。我查看了同一个目录并找到了一个名为 cookie.rb 的文件,我尝试以类似的方式对其进行修改。

def to_s
  buf = ''
  buf << @name << '='
  #buf << (@value.kind_of?(String) ? CGI::escape(@value) : @value.collect{|v| CGI::escape(v) }.join("&"))
    buf << (@value.kind_of?(String) ? @value : @value.collect{|v| (v) }.join("&"))
  buf << '; domain=' << @domain if @domain
  buf << '; path=' << @path if @path
  buf << '; expires=' << CGI::rfc1123_date(@expires) if @expires
  buf << '; secure' if @secure
  buf << '; HttpOnly' if @http_only
  buf
end

不幸的是,这似乎不起作用。在新的 Rails 2.3.2 中,cookie 不断得到 URL 编码。我知道关闭 URL 编码并不是最好的主意,但在遗留应用程序退役之前我没有太多选择。不幸的是,我无法访问旧代码来添加对 cookie 的 URL 解编码的支持,因此我必须确保使用正确的序列(包括斜杠)编写旧 cookie。如果有人能告诉我如何在 Rails 2.3.2 中关闭 URL 编码,将不胜感激。
谢谢。

【问题讨论】:

    标签: ruby-on-rails cookies url-encoding


    【解决方案1】:

    在进行了一些挖掘之后,我找到了我的问题的答案,我在这里记录下来,以防它对其他人有用。

    为了在 Rails 2.3.2 中关闭 URL 编码,需要编辑以下文件:actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/response.rb

    在第 70 行左右设置了 cookie 的 ID 和值。我对 URL 编码进行了以下更改:

    cookie = Utils.escape(key) + "=" +
        #value.map { |v| Utils.escape v }.join("&") +
        value.map { |v| v }.join("&") +
        "#{domain}#{path}#{expires}#{secure}#{httponly}"
    

    注意:此修改仅影响标准 cookie - 不影响 Rails 在 2.3.2 版本中用作会话数据的 cookie。

    免责声明:我绝不建议将此修改作为最佳做法。仅出于处理要求 cookie 采用特定格式的遗留代码要求的特定原因进行此修改。更好的选择甚至是修改遗留代码以处理 URL 编码。不幸的是,这个选项对我来说是关闭的,所以我不得不修改底层的 Rails 代码——这不是我通常推荐的。当然,不言而喻,进行这种类型的修改存在每次升级 Rails 安装时都必须重新解决问题的风险,因为底层代码可能会发生变化。这实际上就是我的情况。当然,如果可能的话,保留 URL 编码也可能有充分的理由(安全性、标准合规性等)。

    【讨论】:

      【解决方案2】:

      一个简单的方法是使用机架方法,

      response["set-cookie"]="id_cookie=this cookie will be not escaped"
      

      【讨论】:

      • 你救了我……但我有一个问题。如何使用此设置域?
      • @Boomerange 你能找到我们如何使用域设置 cookie 吗?
      • @AmitkumarJha 嗨,我只能通过使用 javascript 来做到这一点。但这没关系。它有效:document.cookie = "#{@cookieName}=#{@cookieContent};domain=domain.com"
      • 这个答案几乎是正确的。 HTTP 标头应该以大写字母开头。只要堆栈上没有任何其他组件使用更正确的Set-Cookie 标头设置cookie,将cookie 设置为set-cookie 就可以工作。例如,如果您使用 devise 进行身份验证,则 devise 将覆盖您的手动 cookie,因为它使用 Set-Cookie 标头。浏览器只会考虑第一个并丢弃另一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 2018-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多