Rails Checkout SSL heroku - ruby-on-rails

I have my app deployed with heroku and have a SSL configured to one of my subdomain(secure.mydomain.com). I would like only order part of my app to use this ssl so in my orders controller I have a before filter to redirect the request to my secure subdomain. However all the session information is lost when it is redirected. I think because of the subdomain. How do I redirect this so that session information (cart info which is stored in db and some id information) can be retrieved. Can some one help please.
THanks
KIran

In your config/intializers/session_store.rb change it to
Yourapp::Application.config.session_store :cookie_store, :key => '_yourapp_session', :domain=>:all
The secret-sauce is the domain... When set to all, cookies will be stored across all subdomains and the main domain.

Related

Rails/Heroku/Cloudflare: Can't verify CSRF token authenticity after domain change

We have a Rails 5.2.3 app in production using Devise 4.6.2 and being deployed at Heroku. The app was using a domain example.com and everything was fine. Today we needed to change that domain to app.example.com (example.com is now a WordPress site) and now when we try to log into the app we're getting:
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 19ms
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request'
One thing I've realized is that now our production app isn't setting the session cookie. Our staging app (which uses an example.herokuapp.com domain) sets a cookie named '_myapp_session' (and it's still working fine), while in our production app there's no cookie being set.
While googling about this I've found some mentions to the session_store.rb config (we didn't even had this file), so I created the file in config/initializers and tried to set to our app.example.com domain and also to domain: :all, but it didn't seem to make any difference.
Rails.application.config.session_store :cookie_store, key: '_app_myapp_session', domain: :all
What I am missing here? Why would the domain change stop the app from creating the session cookie?
Oh, and we're using Cloudflare as our DNS and its __cfduid cookie is being correctly set. Could that be related?
So, apparently it was indeed related to Cloudflare. Our app.example.com entry on Cloudflare's DNS was "proxied" and once I've set it to "DNS only" and waited a few minutes our session cookies started appearing again.
I've just now realized that Cloudflare has its own cache, so I've purged that and will try to use the "proxied" setting again, but if that doesn't work I'll just use it as DNS.
If someone has details on why Cloudflare's proxied setting would stop the cookies from being set, please let me know. Thanks!
Did you read this post about Cloudflare cached pages and CSRF?
Poor tl;dr: If you cache a page with a CSRF protected form you have to update de CSRF using Ajax.
https://blog.cloudflare.com/the-curious-case-of-caching-csrf-tokens/

Sharing session across rails apps on different subdomains

I am trying to implement a single-sign-on solution for multiple rails (v3.2) apps hosted at different subdomains of example.com
One app serves as an identity provider, uses devise for auth, and sits at users.example.com
The other apps rely on the identity provider for authentication, use devise+omniauth, with domains of [app1.example.com, app2.example.com, and example.com].
This blog entry inspired much of my implementation: http://blog.joshsoftware.com/2010/12/16/multiple-applications-with-devise-omniauth-and-single-sign-on/
I have it working fine, but the problem remains that the sessions are not shared so after I log in on the identity provider, I still have to make a call from each of the other apps to authenticate and I need this to be seemless to the user.
I tried using the same secret token at secret_token.rb, same session key at session_store.rb and :domain => :all (also tried '.example.com' and 'example.com' as values). Still no luck.
Doing the above, I see in a session.inspect that after login on the identity provider the session variable "warden.user.user.key" is populated. When I immediately go to the app on app1.example.com, the session.inspect shows the same session_id and _csrf_token but the "warden.user.user.key" variable is now missing.
I feel like I am missing something silly.. Any ideas what that may be?
I think there is another SO question about getting a single cookie to work across subdomains that would answer yours:
https://stackoverflow.com/a/10403338/2573896
Also, I can imagine that using a memcached cluster with dalli and memcached as your session store would work as well:
http://awesomerails.wordpress.com/2011/08/23/rails-3-memcached-session-store/
For the purpose of your application, the first solution makes more sense though.

Configuring Rails App to handle multiple subdomains and multiple cookies

I have a rails app which supports multiple domains and each domain may have multiple subdomains.
Users visiting mydomain1.com do not receive the same experience as mydomain2.com (although the base behaviour of the apps is the same)
Therefore, if a user is logged in to mydomain1.com, it shouldn't then be logged in to mydomain2.com
If a user is logged in to france.mydomain1.com, it should then be logged in to germany.mydomain1.com
Previously, I've handled this by setting the domain in the session store configs:
MyApp::Application.config.session_store :cookie_store, :key => '_MyApp_session', :domain => APP_CONFIG[:domain]
I'm trying to work out the best way to handle this with multiple domains?
I've tried hacking around ActionDispatch::Callback but the request is not available from within there.
Can anybody suggest a good way of supporting multiple cookies from within one app?
Ideally I'd like to create a fresh cookie for each subdomain.
You should do that:
class ActionDispatch::Session::MultiDomainStore < ActionDispatch::Session::CookieStore
def initialize(app, options = {})
super(app, options.merge!(:domain => compute_domain(app)))
end
def compute_domain(app)
...
end
end
MyApp::Application.config.session_store :multi_domain_store, :key => '_MyApp_session'
I.e. your domain should start with the dot.
It shouldn't be an issue as cookies are only valid per domain. You can have a _MyApp_session for example1.com and one for example2.com. The cookies are managed by the browser and only sent to the host if the domain matches.
Say you visit example1.com and log in and you will get a cookie with the value abcdef123. Then you log into example2.com and you will get another cookie with a random string uvwxyz890.
If you return to example1.com later, the browser will only send the cookies that are valid for this domain to your app. Your app won't have to manage anything and you don't have to hack anything.

How to handle session domains in a cname forward supporting rails saas software

I have read
How to give cname forward support to saas software
Rails - Multiple top level domains and a single session/cookie
But I am unable to get a solution for the following setup:
A SaaS Webapp in Rails is running under example.com
All users have a sumbdomain e.g. user1.example.com
Users can create a cname forwarding eg. exampleapp.user1.com -> user1.example.com
It is all working until a user tries to log in via exampleapp.user1.com. The SaaS app fails to set the session domain right, because it is configured static on app startup.
config.action_controller.session = {
:session_key => '_example_session',
:domain => ".example.com",
:secret => 'abc'
}
The Request fails with a ActionController::InvalidAuthenticityToken. And that is correct, because the domain changed from .example.com to exampleapp.user1.com.
How do I change the domain config during runtime? I know that the "incoming" domain exampleapp.user1.com belongs to user1, so I want to do something like that in the controller:
session :domain => 'exampleapp.user1.com'
Or can I always set the session domain on the current request domain?
I know that it's possible somehow, because some apps provide that functionality.
Thanks in advance!
:domain => :all on the cookie config may work.
For CNAME'd domains, it will be set to .theirdomain.com
For your custom subdomain, it will go to .yourdomain.com, which may or may not be good
Just don't set the domain, since apparently you don't need to share a session cookie across example.com and user1.example.com. By not specifying a domain, the default cookie behavior is just to be set for the current request domain.

Access rails session information by session id

I'm using the default cookie based session store. Basically, I'm using heroku and I need to go from my app: http://test1.myapp.com over to heroku for one page: http://myapp.heroku.com/billing - so I need to access the session when I go to the heroku url. I'd like to access the session[:user_id] on the heroku page, but when is go to the heroku page a new the session is generated.
I was thinking I could pass the session_id on the main url in the querystring, but I don't know how to access it from the heroku url page.
I tried this:
session[params[:sid]][:user_id]
but it's not working. Is it possible to access session information if you know the session id? Or is there another way to read session information from another url (but all in the same rails app)?
Thanks.
In order for that to work you will need to set up your domain in Heroku so that the Heroku app is running under the same TLD as the main app. To do that, add your domain to your billing app like so:
$ heroku domains:add billing.myapp.com
Make sure to follow Heroku's instructions to set up your DNS.
Your billing app will then live at http://billing.myapp.com/billing (on Heroku). That way the controller should be able to access the same session and cookies.
Be sure to set the session domain in environments/production.rb in both apps:
config.action_controller.session = { :domain => ".myapp.com" }
I should also mention that you might consider using some kind of shared authentication or token authentication between the apps, since cookies can potentially be hacked or otherwise compromised.

Resources