Rails在仅两个子域之间共享Cookie,并在所有其他子域上使用单独的Cookie。

huangapple go评论62阅读模式
英文:

Rails share cookies across only 2 subdomains, and use separate cookie for all other subdomains

问题

我有一个使用Devise进行身份验证的Rails 7 SaSS应用程序,该应用程序在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

因此,我的想法是,我实际上需要在较早的时候动态地设置:cookie_store - 比如在中间件中 - 这样我们可以在wwwdashboard子域上使用一个设置,而在任何其他子域或域上使用完全不同的设置。然而,我现在卡住了。我应该如何进行这些调整?

英文:

I have a Rails 7 SaSS app using Devise for authentication, that signs up a new user on the www.my-site.com subdomain and redirects them to the actual app after signup at dashboard.my-site.com.

I'm able to accomplish this easy enough with the following session_store.rb code:

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

But the problem is that my app allows users to have custom subdomains - which should have totally separate cookies - for example, a-customer-subdomain.my-site.com

So my thought is that I will actually need to set the :cookie_store dynamically sometime earlier - like in Middleware - so we use one setting for www and dashboard subdomain and an entirely different one for any other subdomain or domain. This is where I find myself stuck though. How can I go about making these adjustments?

答案1

得分: 1

以下是您要翻译的内容:

"Looking at "What does Rails 3 session_store domain :all really do?"", but also "Building a Rails App With Multiple Subdomains" by Prathamesh Sonpatki (March 2020), you should indeed use a middleware to dynamically set the cookie domain based on the incoming request.

# 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

This middleware will set the session cookie domain to ['dashboard.my-site.com', 'www.my-site.com'] if the request is coming from either of those hosts. For any other host, it will set the session cookie domain to the host of the request.

You will need to add this middleware to your middleware stack. You can do this in your application configuration:

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

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

This will insert the DynamicCookieDomain middleware into your middleware stack, ensuring that it is run for every request.

That should address the requirement of having different cookie settings for www and dashboard subdomains versus any other subdomain.

The custom_domain method in the middleware checks the host of the incoming request.

  • If the host is either www.my-site.com or dashboard.my-site.com, it sets the cookie domain to ['dashboard.my-site.com', 'www.my-site.com']. This means that the session cookie will be shared between these two subdomains.

  • For any other host (which would be any other subdomain or domain), it sets the cookie domain to the host of the request. This means that the session cookie will be specific to that subdomain or domain and will not be shared with www.my-site.com or dashboard.my-site.com.

This dynamic setting of the cookie domain based on the incoming request should allow you to have one setting for www and dashboard subdomains and a different setting for any other subdomain or domain.


This is slightly different from this answer, which sets the cookie domain to the second-level domain (e.g., my-site.com) if the request is coming from a subdomain, and to :all otherwise. This would share cookies across all subdomains of my-site.com.

In contrast, here, the cookie domain is set to ['dashboard.my-site.com', 'www.my-site.com'] if the request is coming from either of those hosts, and to the host of the request otherwise. This shares cookies between dashboard.my-site.com and www.my-site.com, but uses separate cookies for all other subdomains.

英文:

Looking at "What does Rails 3 session_store domain :all really do?", but also "Building a Rails App With Multiple Subdomains" by Prathamesh Sonpatki (March 2020), you should indeed use a middleware to dynamically set the cookie domain based on the incoming request.

# 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

This middleware will set the session cookie domain to ['dashboard.my-site.com', 'www.my-site.com'] if the request is coming from either of those hosts. For any other host, it will set the session cookie domain to the host of the request.

You will need to add this middleware to your middleware stack. You can do this in your application configuration:

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

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

This will insert the DynamicCookieDomain middleware into your middleware stack, ensuring that it is run for every request.

That should address the requirement of having different cookie settings for www and dashboard subdomains versus any other subdomain.

The custom_domain method in the middleware checks the host of the incoming request.

  • If the host is either www.my-site.com or dashboard.my-site.com, it sets the cookie domain to ['dashboard.my-site.com', 'www.my-site.com']. This means that the session cookie will be shared between these two subdomains.

  • For any other host (which would be any other subdomain or domain), it sets the cookie domain to the host of the request. This means that the session cookie will be specific to that subdomain or domain and will not be shared with www.my-site.com or dashboard.my-site.com.

This dynamic setting of the cookie domain based on the incoming request should allow you to have one setting for www and dashboard subdomains and a different setting for any other subdomain or domain.


This is slightly different from this answer, which sets the cookie domain to the second-level domain (e.g., my-site.com) if the request is coming from a subdomain, and to :all otherwise. This would share cookies across all subdomains of my-site.com.

In contrast, here, the cookie domain is set to ['dashboard.my-site.com', 'www.my-site.com'] if the request is coming from either of those hosts, and to the host of the request otherwise. This shares cookies between dashboard.my-site.com and www.my-site.com, but uses separate cookies for all other subdomains.

huangapple
  • 本文由 发表于 2023年6月15日 05:51:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定