我正在尝试构建一个多租户应用,其中不同的银行由子域分隔。这部分工作正常。现在银行产品还有一个多租户级别。
这就是我试图实现上述解决方案的方法
around_filter :scope_current_bank, :scope_current_product
before_filter :authenticate_user!
helper_method :current_bank, :current_product
def current_bank
@current_bank = Bank.find_by_subdomain!(request.subdomains.first)
end
def current_product
if user_signed_in?
@current_product = current_bank.products.find_by_id(params[:product_id])
else
@current_product = current_user.product
end
end
def scope_current_bank
Bank.current_id = current_bank.id
yield
ensure
Bank.current_id = nil
end
def scope_current_product
Product.current_id = (current_product.id rescue nil)
yield
ensure
Product.current_id = nil
end
现在的问题是当用户输入时, scope_current_product 方法调用user_signed_in ?,显然它失败了,因为product_id是nil。现在它进入了else块,之后我希望它将 authenticate_user!称为before_filter,但它不会发生,因为身份验证已经完成。所以我得到一条消息说认证失败了。
他们是否可以再次调用authenticate_user?
答案 0 :(得分:1)
虽然不是直接的答案,但希望这会给你一些想法:
<强>授权强>
也许你应该看一下 - Is there a difference between authentication and authorization? - 关于这个问题有一个good RailsCast
我认为您的问题归结为您需要对用户进行身份验证一次(登录/注销),但应该授权该用户使用不同的资源
<强>代码强>
A devise user can belong to only on product
- 我建议这样做:
#app/models/product_user.rb
Class ProductUser < ActiveRecord::Base
belongs_to :product
belongs_to :user
end
#app/models/product.rb
Class Product < ActiveRecord::Base
has_many :product_users
has_many :users, through: :product_users
end
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :product_users
has_many :products, through: :product_users
end
这是典型的has_many :through关联:
@user.products
@product.users
<强>惭惭强>
这意味着您可以使用CanCan执行以下操作:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user
can :manage, Product, users.exists?(user.id)
else
can :read, :all
end
end
end
这使您可以控制用户可以编辑/访问的产品。显然我的代码需要调整,但我希望它向您展示授权的价值,而不是尝试进行多次身份验证