由于某些原因,将:all
替换为域名在我的情况下无法正常工作(rails 3.2.11)。需要使用自定义中间件来解决此问题。以下是该解决方案的摘要。
tl;dr:您需要编写自定义Rack中间件,并将其添加到conifg/environments/[production|development].rb
中。这是针对Rails 3.2.11的。
Cookie会话通常仅存储在顶级域中。
如果您查看Chrome -> 设置 -> 显示高级设置… -> 隐私/内容设置… -> 所有cookie和站点数据… -> 搜索{yourdomain.com}
您会发现sub1.yourdomain.com
、othersub.yourdomain.com
和yourdomain.com
将分别显示为不同的条目。
挑战在于要跨所有子域使用相同的会话存储文件。
步骤1:添加自定义中间件类
这就是Rack中间件发挥作用的地方。以下是一些相关的rack&rails资源:
以下是您应该在lib
中添加的自定义类
这是由@Nader编写的,大家都应该感谢他
class CustomDomainCookie
def initialize(app, default_domain)
@app = app
@default_domain = default_domain
end
def call(env)
host = env["HTTP_HOST"].split(':').first
env["rack.session.options"][:domain] = custom_domain?(host) ? ".#{host}" : "#{@default_domain}"
@app.call(env)
end
def custom_domain?(host)
host !~ /#{@default_domain.sub(/^\./, '')}/i
end
end
基本上这个做法的作用是将所有的cookie会话数据映射回与根域名相等的同一个cookie文件中。
第二步:添加到Rails配置中
现在你已经在lib中有了一个自定义类,请确保进行了自动加载。如果这对你来说意味着什么,可以看看这里:Rails 3 autoload
第一件事就是要确保你正在系统范围内使用cookie存储。在config/application.rb
中,我们告诉Rails使用cookie存储。
config.session_store :cookie_store,
:key => '_yourappsession',
:domain => :all
这里提到的原因是因为有一行代码 :domain => :all
。有些人建议使用 :domain => ".yourdomain.com"
来代替 :domain => :all
。但出于某些原因,这种方法对我不起作用,我需要像上面描述的那样使用自定义的 Middleware 类。
然后在你的config/environments/production.rb
文件中添加:
config.middleware.use "CustomDomainCookie", ".yourdomain.com"
请注意,前面的点是必要的。有关原因,请参见“ 子域cookie是否可以在上级域请求中发送?”。
然后,在您的config/environments/development.rb
文件中添加:
config.middleware.use "CustomDomainCookie", ".lvh.me"
lvh.me技巧映射到本地主机。非常棒。有关子域的更多信息,请参见此Railscast和此注释。
希望这样做就可以了。老实说,我不完全确定为什么这个过程如此复杂,因为我觉得跨子域站点很常见。如果有人对每个步骤背后的原因有更深入的了解,请在评论中启迪我们。
config.secret_key_base
,否则将无法解码 cookie。 - Bruno BuccoloCacheStore
将会话存储在memcached中怎么办? - Amit PatelAppname::Application.config.session_store :cookie_store, key: '_appname_session', domain: :all, tld_length: 2
- user1515295