How do I connect multiple devise apps for a single login to any of the apps?
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
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.
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
- 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.
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.
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:
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).
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.
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.
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.
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).
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.
Thanks for sharing this Thomas! That sounds like a pretty good solution. Were there any gotchas that you ran into?
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'!