如何创建管理子域来管理 Rails 中的子域

发布于 2024-08-22 07:17:22 字数 3591 浏览 6 评论 0原文

我正在使用 AuthLogic 和 dhh 在 这篇博文,一切都很顺利,符合预期。我想要弄清楚的是如何创建一个像“admin”或“host”这样的子域,该子域将让用户通过 AuthLogic 进行身份验证(这可能很简单,无需提及)来管理子域。所以基本上,所有子域都会正常运行,除了 admin.site.com ,它会转到自己的控制器和布局。

dhh 建议抛出一个异常来重定向,但我不确定它会去哪里,似乎没有对我来说很简单,有什么想法吗?

编辑 我认为我使用 AuthLogic 的事实在这里很重要,因为一旦经过身份验证的 AuthLogic 将用户发送到 /account,子域逻辑不会将用户转发到任何地方 - 所以我的问题可能与如果user 是 root 用户,登录到 admin 子域。

这是我们迄今为止实现的代码

公司模式

class Company < ActiveRecord::Base
  has_many :users
  has_many :brands, :dependent => :destroy

  validates_presence_of     :name, :phone, :subdomain
  validates_format_of       :subdomain, :with => /^[A-Za-z0-9-]+$/, :message => 'The subdomain can only contain alphanumeric characters and dashes.', :allow_blank => true
  validates_uniqueness_of   :subdomain, :case_sensitive => false
  validates_exclusion_of    :format, :in => %w( support blog billing help api www host admin manage ryan jeff allie), :message => "Subdomain {{value}} is not allowed."
  before_validation         :downcase_subdomain

  protected
    def downcase_subdomain
      self.subdomain.downcase! if attribute_present?("subdomain")
    end
end

子域公司模块

module SubdomainCompanies
  def self.included( controller )
    controller.helper_method(:company_domain, :company_subdomain, :company_url, :company_account, :default_company_subdomain, :default_company_url)
  end

  protected

    # TODO: need to handle www as well
    def default_company_subdomain
      ''
    end

    def company_url( company_subdomain = default_company_subdomain, use_ssl = request.ssl? )
      http_protocol(use_ssl) + company_host(company_subdomain)
    end

    def company_host( subdomain )
      company_host = ''
      company_host << subdomain + '.'
      company_host << company_domain
    end

    def company_domain
      company_domain = ''
      company_domain << request.domain + request.port_string
    end

    def company_subdomain
      request.subdomains.first || ''
    end

    def default_company_url( use_ssl = request.ssl? )
      http_protocol(use_ssl) + company_domain
    end      

    def current_company
      Company.find_by_subdomain(company_subdomain)
    end

    def http_protocol( use_ssl = request.ssl? )
      (use_ssl ? "https://" : "http://")
    end 
end

应用程序控制器

class ApplicationController < ActionController::Base
  include SubdomainCompanies

  rescue_from 'Acl9::AccessDenied', :with => :access_denied

  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
  helper_method :current_user_session, :current_user, :current_company_name
  filter_parameter_logging :password, :password_confirmation 
  before_filter :check_company_status

  protected

    def public_site?
      company_subdomain == default_company_subdomain
    end

    def current_layout_name
      public_site? ? 'public' : 'login'
    end

    def check_company_status
      unless company_subdomain == default_company_subdomain
        # TODO: this is where we could check to see if the account is active as well (paid, etc...)
        redirect_to default_company_url if current_company.nil? 
      end
    end
end

I am using AuthLogic and the subdomain method that dhh covered in this blog post, everything is working great, and as expected. What I'm trying to figure out is how to create a subdomain like 'admin' or 'host' that will have a user authenticated from AuthLogic (this may be trivial and unnecessary to mention) that will manage the subdomains. So basically, all subdomains will act normally, except admin.site.com which will go to its own controller and layout..

dhh suggested just throwing in an exception to redirect, but I'm not sure where that goes, it didnt seem that simple to me, any ideas?

EDIT
I think that the fact I am using AuthLogic is important here, because the subdomain logic isnt forwarding users anywhere, once authenticated AuthLogic sends the user to /account - so my question may be related to how do I tell AuthLogic to a different spot if the user is a root user, logging into the admin subdomain..

Here is the code we have implemented thus far

Company Model

class Company < ActiveRecord::Base
  has_many :users
  has_many :brands, :dependent => :destroy

  validates_presence_of     :name, :phone, :subdomain
  validates_format_of       :subdomain, :with => /^[A-Za-z0-9-]+$/, :message => 'The subdomain can only contain alphanumeric characters and dashes.', :allow_blank => true
  validates_uniqueness_of   :subdomain, :case_sensitive => false
  validates_exclusion_of    :format, :in => %w( support blog billing help api www host admin manage ryan jeff allie), :message => "Subdomain {{value}} is not allowed."
  before_validation         :downcase_subdomain

  protected
    def downcase_subdomain
      self.subdomain.downcase! if attribute_present?("subdomain")
    end
end

SubdomainCompanies Module

module SubdomainCompanies
  def self.included( controller )
    controller.helper_method(:company_domain, :company_subdomain, :company_url, :company_account, :default_company_subdomain, :default_company_url)
  end

  protected

    # TODO: need to handle www as well
    def default_company_subdomain
      ''
    end

    def company_url( company_subdomain = default_company_subdomain, use_ssl = request.ssl? )
      http_protocol(use_ssl) + company_host(company_subdomain)
    end

    def company_host( subdomain )
      company_host = ''
      company_host << subdomain + '.'
      company_host << company_domain
    end

    def company_domain
      company_domain = ''
      company_domain << request.domain + request.port_string
    end

    def company_subdomain
      request.subdomains.first || ''
    end

    def default_company_url( use_ssl = request.ssl? )
      http_protocol(use_ssl) + company_domain
    end      

    def current_company
      Company.find_by_subdomain(company_subdomain)
    end

    def http_protocol( use_ssl = request.ssl? )
      (use_ssl ? "https://" : "http://")
    end 
end

Application Controller

class ApplicationController < ActionController::Base
  include SubdomainCompanies

  rescue_from 'Acl9::AccessDenied', :with => :access_denied

  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
  helper_method :current_user_session, :current_user, :current_company_name
  filter_parameter_logging :password, :password_confirmation 
  before_filter :check_company_status

  protected

    def public_site?
      company_subdomain == default_company_subdomain
    end

    def current_layout_name
      public_site? ? 'public' : 'login'
    end

    def check_company_status
      unless company_subdomain == default_company_subdomain
        # TODO: this is where we could check to see if the account is active as well (paid, etc...)
        redirect_to default_company_url if current_company.nil? 
      end
    end
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羁〃客ぐ 2024-08-29 07:17:22

查看 subdomain-fu 它允许您根据子域路由到不同的控制器和操作。我已经就这个主题做了Railscasts Episode

它可能看起来像这样。

# in routes.rb
map.manage_companies '', :controller => 'companies', :action => 'index', :conditions => { :subdomain => "admin" }

这需要在路由列表中位于足够高的位置,以便在它之前没有其他内容匹配。

Look into subdomain-fu which allows you to route to different controllers and actions based on the subdomain. I have done a Railscasts Episode on the subject.

It might looks something like this.

# in routes.rb
map.manage_companies '', :controller => 'companies', :action => 'index', :conditions => { :subdomain => "admin" }

This will need to be high enough up in the routes list so nothing else is matched before it.

稚然 2024-08-29 07:17:22

对于 RAILS 2.3: 您可以下载完整的示例应用程序(带有分步教程),展示如何使用 Devise gem 进行身份验证来实现管理子域、主域和多个用户子域以及用于管理子域的 subdomain-routes gem。链接如下:Rails 2.3 的子域身份验证

对于 RAILS 3: 这是 具有身份验证功能的 Rails 3 子域的完整示例实现(以及详细的教程)。在 Rails 3 中执行此操作比在 Rails 2 中容易得多(无需插件)。

FOR RAILS 2.3: You can download a full example app (with a step-by-step tutorial) showing how to implement an admin subdomain, a main domain, and multiple user subdomains using the Devise gem for authentication and the subdomain-routes gem for managing subdomains. Here's the link: subdomain authentication for Rails 2.3.

FOR RAILS 3: Here's a complete example implementation of Rails 3 subdomains with authentication (along with a detailed tutorial). It's much easier to do this in Rails 3 than in Rails 2 (no plugin required).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文