英文:
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
- 比如在中间件中 - 这样我们可以在www
和dashboard
子域上使用一个设置,而在任何其他子域或域上使用完全不同的设置。然而,我现在卡住了。我应该如何进行这些调整?
英文:
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
ordashboard.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
ordashboard.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
ordashboard.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
ordashboard.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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论