我有一个rails 7sass应用程序使用Devise进行身份验证,它在www.my-site.com个子域上注册一个新用户,并在dashboard.my-site.com注册后将他们重定向到实际的应用程序.

我可以通过下面的SESSION_Store.rb代码很容易地完成这项工作:

Rails.application.config.session_store :cookie_store, key: "_myapp_session", domain: ["dashboard.my-site.com", "www.my-site.com"], tld_length: 2

但问题是,我的应用程序允许用户拥有自定义子域名--它们应该有完全独立的Cookie--例如,a-customer-subdomain.my-site.com

所以我的 idea 是,我实际上需要在某个更早的时候动态设置:cookie_store--就像在Middleware中一样--所以我们对wwwdashboard子域使用一种设置,而对任何其他子域或域使用完全不同的设置.然而,这就是我发现自己陷入困境的地方.我该如何着手进行这些调整呢?

推荐答案

看一下"What does Rails 3 session_store domain :all really do?",但也看到Prathamesh Sonpatki(2020年3月)的"Building a Rails App With Multiple Subdomains",您确实应该使用中间件来根据传入的请求动态设置Cookie域.

# lib/middleware/dynamic_cookie_domain.rb
class DynamicCookieDomain
  def initialize(app)
    @app = app
  end

  def call(env)
    host = env["HTTP_HOST"].split(':').first
    Rails.application.config.session_store :cookie_store, key: "_myapp_session", domain: custom_domain(host), tld_length: 2
    @app.call(env)
  end

  private

  def custom_domain(host)
    case host
    when 'www.my-site.com', 'dashboard.my-site.com'
      ['dashboard.my-site.com', 'www.my-site.com']
    else
      host
    end
  end
end

如果请求来自这两个主机中的任何一个,则此中间件会将会话Cookie域设置为['dashboard.my-site.com', 'www.my-site.com'].对于任何其他主机,它会将会话Cookie域设置为请求的主机.

您需要将此中间件添加到您的中间件堆栈中.您可以在应用程序配置中执行此操作:

# config/application.rb
require_relative '../lib/middleware/dynamic_cookie_domain'

module YourApp
  class Application < Rails::Application
    # ...
    config.middleware.use DynamicCookieDomain
    # ...
  end
end

这将把DynamicCookieDomain个中间件插入到您的中间件堆栈中,确保对每个请求都运行它.

这应该解决了wwwdashboard子域与任何其他子域具有不同Cookie设置的要求.

中间件中的custom_domain方法判断传入请求的主机.

  • 如果主机是www.my-site.comdashboard.my-site.com,它会将Cookie域设置为['dashboard.my-site.com', 'www.my-site.com'].这意味着会话Cookie将在这两个子域之间共享.

  • 对于任何其他主机(可以是任何其他子域或域),它将Cookie域设置为请求的主机.这意味着会话Cookie将特定于该子域或域,不会与www.my-site.comdashboard.my-site.com共享.

这种基于传入请求的Cookie域的动态设置应该允许您对wwwdashboard子域有一种设置,而对任何其他子域或域有不同的设置.


这与this answer略有不同,后者如果请求来自子域,则将Cookie域设置为第二级域(例如,my-site.com),否则设置为:all.这将在my-site.com的所有子域之间共享Cookie.

相反,在这里,如果请求来自这两个主机中的任何一个,则Cookie域设置为['dashboard.my-site.com', 'www.my-site.com'],否则将请求的主机设置为['dashboard.my-site.com', 'www.my-site.com'].它共享dashboard.my-site.comwww.my-site.com之间的Cookie,但对所有其他子域使用单独的Cookie.

Ruby-on-rails相关问答推荐

带有data-turbo的rails`link_to‘未获得turbo_stream请求格式

Trailblazor 操作 -> 集合 :attribute(has_many 通过关联) 与填充器 -> 如何填充 Reform::Form 形式的 slugs 数组?

Rails 7,Hotwire 动态表单,更新值不起作用

Rails 7 - has_many_attached 在加载新附件时删除旧附件

Rails:关于yields

Rails 模型.有效吗?刷新自定义错误并错误地返回 true

rails select标签,预先 Select 了多个值

如何让 Rspec 运行嵌套在文件夹下的所有测试?

如何使用 capistrano deploy 定位特定的提交 SHA

没有要加载的文件 - readline

是否有不涉及删除 Gemfile.lock 的在任何源中找不到 *gem*错误的修复?

错误未初始化的常量 AWS (NameError)

如何测试自定义验证器?

Rails:如何修复‘生产’环境缺少 secret_key_base

ActiveRecord 中多列的索引

Ruby 1.87 与 1.92 Date.parse

将现有的 html.erb 转换为 Haml

ArgumentError:ApplicationController 的副本已从模块树中删除,但仍处于活动状态

警告:运行 ruby​​ 或 gem 命令时不安全的世界可写目录

在 Rails 4.1 中,如何通过枚举符号查找记录?