简体   繁体   中英

Rails: Multi-tenancy with Devise and Apartment gem

I'm creating a multi-tenant app using devise and apartment gems. I'm using postgresql database. I've created a few models. 'User' model is in global namespace and it is used for authentication by devise gem. There are some other models (eg Project, Setting etc) which are in tenant namespace.

I've followed this tutorial for creating this multi-tenance app: https://gorails.com/episodes/multitenancy-with-apartment?autoplay=1

The multi-tenancy feature is working fine in a sense that if I login to two separate subdomains (eg user1.example.com and user2.example.com) from their relevant accounts (eg user1@gmail.com and user2@gmail.com) it works fine and I can create unique records for each tenant.

Now, the issue is, I can login to any subdomain using any email and the tenant records would be shown based on the subdomain present in address bar. eg I can login with user1@gmail.com at user2.example.com and it will succesfully autheticate and will display records of user2 tenant.

My question is, while logging in how can I check if current user's subdomain matches with the requested subdomain (on address bar), if it matches proceed with authentication and display admin dashboard and if not (logging in from wrong subdomain or from TLD) authenticate the user but redirect him to his relevant subdomain's dashboard. How can I do that?

UPDATE # 1:

I was able to restrict the user login to their specific sub-domain by using minor devise configuration. In devise.rb file I've added :subdomain attribute in the list of authentication keys, so it will also check for correct subdomain value together with email, however I'm not sure how to provide the subdomain value to the login form correctly. I can use a hidden field like this in login form <%= f.hidden_field:subdomain, value: request.subdomain %> but it is hackable as user can change it's value from browser inspector.

UPDATE # 2:

I was able apply a fool proof method to restrict user login to their specific sub-domain. I've followed this method: https://github.com/plataformatec/devise/wiki/How-to:-Scope-login-to-subdomain

Now, my only issue is that user is unable to login from TLD (eg example.com), I want it to be possible but after login user must be redirected to their relevant sub-domain with alive session.

Supposing you're saving the subdomain on the User model, you can create a validation in your controller you can use something like:

if user.subdomain == request.subdomain
  redirect_to root_url(subdomain: user.subdomain)
else
  everything_is_ok
end

If you store your subdomain in your User table and if you check it via request.subdomain then how can someone join the another tenant(company) ? They can be included in more than one company.

That's why, I created 2 middle tables to handle it.

  • I've user table for all of my users.
  • I've account table to store subdomains with its creator.
  • And I've account_permissions to find out who are authorized to where.

So, when user1 comes to user2.example.com , I'm querying to my Account_permissions and if it has permission for user2.example.com , I let it go.

This way seems like sense.

If someone still have a similar problem and is not very expert in ROR, I suggest building the base app first and then making it multi_tenant using that video. After building your app, you only need to install the apartment gem, then make a model which stores tenants information and then exclude it from being multi_tenanted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM