Ask A Question

Notifications

You’re not receiving notifications from this thread.

How do I connect multiple devise apps for a single login to any of the apps?

Thomas Bush asked in Gems / Libraries

For a rails/devise project I'm trying to figure out how to have the same devise login (email/password) work for multiple apps on different domains. I can't figure out if this would that be considered "Single Sign On” or “Remote Authenticatable”?

I want this to be seamless for example:

site-1.com/login
site-2.com/login

site-1.com/sign-up
site-2.com/sign-up

site-1.com/sign-out
site-2.com/sign-out
Reply

Hey Thomas,

You'll definitely want some sort of single sign on process. Most of the results will probably come up on google if you search for that. I did a little searching and couldn't find anything really good. Basically you'll want a primary site that can handle the authentication and then send you back securely to the main sites so they can log you in. It's kind of similar to how OAuth works.

You may want to check out CAS whcih is a central authentication service. There's a devise plugin for it (https://github.com/nbudin/devise_cas_authenticatable) but I've never built anything with it. Pretty sure a project like 6 years ago that I worked on used a CAS but I wasn't around when they set it up. I should probably make some screencasts on this at some point. It seems really convoluted from all the tutorials but I'm sure it's simpler than they make it out to be.

Reply

Thanks Chris! A tutorial on this would be awesome - everything I find is so confusing. I have wanted to do this exact same thing for a personal project for a while now, but hadn't had the time to look into it in depth. This project for work is just forcing the issue.

Just to make sure I am understanding this flow correctly:

  • Go to site-1.com/login
  • user is redirected to login-site.com
  • authenticate
  • redirected back to site-1.com/

Why I ask specifically is changing domains throws off our analytics, namely Marketo. This is why I was hoping to avoid such a solution initially. If this is unavoidable than so be it. Just wan to make sure I can explain this correctly to the analytics guys/my boss.

Reply

Yep, that should basically be it, but the last step with the redirect, there will be something like a token that gets sent back that is verified.

The reason for that is because separate domains can only set cookies for their own. Subdomains can be included but not different domains which would be a security issue. Browsers won't let you set cookies between separate domains.

You'll have to get a token back that you can verify and set a cookie on the other domain as well to know that you're logged in on the other site. Basically you're making a microservice for authentication.

Not entirely sure what you'll need to do with the analytics, but that's definitely no fun.

Reply

Chris, I had one more thought I was hoping I could get and experienced opinion on. The apps I am talking about a stores, we have one main store (150 products), 5 niche stores (20 or less products). All niche stores are just subsets of the main store with different branding, design, content etc.

What if it was all just one app?
I could key off domain with something like:

store_controller

def show
    @store = Store.find_by(domain: request.host)
end

Than I could easily list products etc through relationships. I would only have one codebase to maintain an a huge reduction in duplicative apps. Devise functionality I desire out of the box (I think).

Reply

Yeah, so you could have one Rails app that responds to all those domains and looks up the store like that. This would be easy to implement and manage (basically how Shopify works). I think you may possibly still need some sort of SSO in order to have the user logged in on the separate domains, but the code can all live in the single app.

Reply

Have you considered using the apartment gem and creating a new tenant when a new user is added? I have a similar situation in my project for subdomains but it with domains as well.

Reply

I would definitely be interested in seeing a screen cast on this as well!

Reply

I have worked out a solution after read a few tutorials - the one included below proving most helpful. I will include the links and a bit more about my apps which will hopefully explain the path a took in hopes that someone else may benefit.

Brittany, thanks for your suggestion, but I don't think apartment gem is what I am looking for - please correct me if I am wrong as this is my first work on an application of this nature. My understanding is that apartment gem would separate out the different tenants into completely different databases, whereas I actually want to share most of the database entires.

My tenants (if I understand the analogy correctly) would be web stores. We have about 120 different products, and 5 stores. Each store just contains some subset of the 120 different products with one store containing all the products. Products have parts (size, color, etc), but basically, there is overlap between stores. Because of the shared data I decided I didn't fit the multi tenant model.

My solution

The conclusion I came to was separate apps with a shared login. One app for the provider, and one app for each client (or store).

Blog Post

I based a lot of my solution of learning from this tutorial blog post and the two corresponding code repositories.

Basically, the provider at the top would have the devise install and manage all users. The client apps use omniauth to authenticate against the provider devise instance. This is accomplished through a custom auth strategy outlined in the post.

Hope this helps someone. I would still love to see if anyone else has a different take on this.

Reply

Thanks for sharing this Thomas! That sounds like a pretty good solution. Were there any gotchas that you ran into?

Reply

Does anyone know if the solution proposed by Thomas Bush works with rails 5 or is the code to change much? Thank you I've find the gem 'doorkeeper'!

Reply

Chiming in real late with a thought (am facing design decision in this realm). Under the assumption one controls all the applications:
1 - set up all applications with same master.key
2 - application acts as an API. Create user there, parent then populates child app with a copy of the user (and user.id would be synched !)
However, this does not synchronise logins. It is also debatable whether one wants those logins synchronised.
Assuming yes, has anyone implemented such a solution?

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,464+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.