how to make rails-issued cookie work cross subdomain - ruby-on-rails

I am having a situation when I am trying to make a RAILS application to be the backend core of my APIs. I am using 'devise' to authenticate the users, which does by putting a session cookie. This is so far perfect. and take in consideration that I am building this on "api.mydomain.com"
Now, I also have a javascript application running on "mydomain.com" which do AJAX calls to the API on the subdomain. I need to have the rails-issued cookie be valid and go on the headers when I make the API calls... It just doesn't.
I tried every single solution that I found on google, where it looks like putting this
Api::Application.config.session_store :cookie_store, key: '_api_session', :domain => ".mydomain.com"
into my config/initializers/session_store.rb was the default answer. this didn't work for me.
I also found some other recommendation on google that I shoudl put that in the environment file. that didn't work either for me.
Help will be appreciated.
Please note: I am running rails 3.2.11 should this matter.

Try using the :domain => :all option.
Source: Railsapps Tutorial on Subdomains (search for "Optional: Allow Sessions To Be Shared Across Subdomains")

I found that there is a better way to do that:
:domain => "*.domain.com"

Related

Implement single sign on functionality in rails 4

Currently I am trying to implement Single Sign On (SSO) in rails 4.
Consider the I have one main app demo.com and three sub-domain apps (basically each one is separate rails application) sub0.demo.com, sub1.demo.com, sub2.demo.com
Now I have to login all of the application through the demo.com (let consider I have same users on all of the applications)
For this I looked into the this post and tried to implement it.
So I have a following questions
Is it the good way for doing this?
As per the given link, I am trying to implement the given functionality for this I have did following steps
As I am working on local, set the domain in /etc/hosts/ file
127.0.0.1 demo.com
127.0.0.1 sub0.demo.com
127.0.0.1 sub1.demo.com
Also made changes in the following files from the sub1.demo.com
session_store.rb
Rails.application.config.session_store :cookie_store, :key => '_tourlyapp_session', :domain => "demo.com"
But it is not working even though I have set the same key for all the application.
Is there any thing I am missing.
Have you tried doorkeeper gem , it is for what you are looking https://github.com/doorkeeper-gem/doorkeeper I have also found this post related to it

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.

sharing sessions between Rails 3.1 applications

I have 2 Rails applications (separated but sharing same top level domain). In development, I run the first application under localhost:3000 and the other one under localhost:3500
These two applications have the same users (not really but let's keep it simple).
So, when a user logs into application 1, I want him to be able to go to application 2 without having to sign-in again.
To do this, I changed the initializer, session_store.rb to:
Iview::Application.config.session_store :cookie_store, :key => '_iview_session', :domain => :all
I hoped this would be enough as, in my understanding, when accessing app. 2, the app. would be looking for the cookie of app 1 and assume the user is logged-in but it doesn't do the trick (at least in development).
What do I miss? Thanks!
Have you tried to set the secret_token.rb initializer to the same key?

How maintain users authentications\sessions through multiple application?

I am using Ruby on Rails 3 and I have 3 web applications:
<site_name>.com
users.<site_name>.com
resources.<site_name>.com
Notice: At this time I have applications on the same server, but in future I can choose to deploy those on separated web servers. So, I would like not use the common solution:
config.session_store :cookie_store, :key => '<whatever key>', :domain => :all
Consider this in your answer.
I would like to handle user authentications\sessions through all those applications so that a user must authenticate himself only one time. That is, I would like to sign in a user on users.<site_name>.com and then maintain its session on browsing other applications.
So, question are:
What do you advice in order to implement these functions? Do that writing own code or using gem(s)\plugin(s)? If the latter, what gem(s)\plugin(s) combination do you advice to use?
I have heard of the OAuth protocoll: in my case (also if at this time I need to authorizate users only through my applications) is it right to use that? If so, what gem(s)\plugin(s) can I use to achieve that?
If you're always going to have these servers on *.<site_name>.com then you could use a cookie written to the <site_name>.com scope to track and authenticate this user. Obviously you do have to be careful about this and make sure that a) the cookie is transferred via HTTPS (secure cookie) and that b) that each server validates the cookie via some sort of web service.
I suggest looking into Warden and the warden_rails gem. On top of this basic well documented authentication foundation you can write "strategies" to validate users using a cookie and read in the session information from a central datasource.
if they all run under the same domain the easiest would be to make sure your cookies are valid for all subdomains. in your production.rb:
config.session_store :cookie_store, :key => '<whatever key>', :domain => :all
the :domain => :all causes your cookies to be valid across all subdomains. just make sure the key and also your session secret token are the same in all apps.

How to secure a Rails app against Firesheep?

I have not been able to find an easy guide for securing a Ruby on Rails app against a Firesheep.
In case you don't know, Firesheep jacks session cookies if your app doesn't force SSL and set the secure flag in the cookie. I had to do some searching to find these two things, so I thought I'd post what I found here and see if there is anything else I'm missing.
Step 1 Force SSL
There are two ways to do this that I found. One is using the ssl_requirement plugin, but this is a pain because you have to specifically specify ssl_required :action1, :action2 in every controller.
The preferable way appears to be by using Rack Middleware, via this post: Force SSL using ssl_requirement in Rails 2 app. Works like a charm.
Step 2 Make cookies secure
For this I followed these directions, which tell you to put the following in your config/environment/production.rb file:
config.action_controller.session = {
:key => 'name_of_session_goes_here',
:secret => 'you need to fill in a fairly long secret here and obviously do not copy paste this one',
:expire_after => 14 * 24 * 3600, #I keep folks logged in for two weeks
:secure => true #The session will now not be sent or received on HTTP requests.
}
This was all pretty straight-forward on my Rails 2.x app. Did I miss anything? Is it different for Rails 3?
Looks pretty good to me. It's pretty similar in Rails 3, though by default the session config is stored in config/initializers/session_store.rb. I usually tweak mine to look something like...
MyApp::Application.config.session_store :cookie_store, :key => '_my_app_session',
:secure => Rails.env == 'production', # Only send cookie over SSL when in production mode
:httponly => true, # Don't allow Javascript to access the cookie (mitigates cookie-based XSS exploits)
:expire_after => 60.minutes
And the secret is held in config/initializers/secret_token.rb:
MyApp::Application.config.secret_token = 'secret secrets are no fun...'
If you have access to your Apache (or whatever) config, you can also force SSL usage at that level. Strikes me as a more appropriate place to do that, but I guess not everyone has that option.
Seeing as this SO post ranks pretty high in Google I thought I'd share the approach I used for securing an app.
If you want to ensure SSL and also ensure secure cookies then you could use a Rack middleware:
https://github.com/tobmatth/rack-ssl-enforcer
I evaluated lots of different options and configuration settings for doing this but the rack middleware felt like the best option with the least amount of config - very easy to deploy. It has some great config options to filter specific rules, hosts, paths etc.
I tested that it does indeed set secure cookies correctly and it does. The one thing I noted was it only did it when logging out and logging in again - but that was using Devise.

Resources