In my session controller, I want to set a cookie when user logs-in.
Say I visit http://buy.example.com/login, and the controller will handle the login as well as the cookie setting like the following:
cookies[:status] = { value: 'y', :domain => :all }
redirect_to referrer_url
I see that the cookie is set under the domain .buy.example.com, instead of .example.com.
The setting :domain => :all is not having any effect at all.
I am using Rails 3.2.11. The test is done in Chrome.
Have you set up your config/initializers/session_store.rb file
YourAppName::Application.config.session_store :cookie_store,
:key => '_yourAppName_session', domain: {
production: '.example.com',
development: '.lvh.me'
}.fetch(Rails.env.to_sym, :all)
With this configuration you can use lvh.me:3000 as the url in development.
Related
In myapp/config/initializers/session_store.rb, I have the following:
Myapp::Application.config.session_store :cookie_store, :key => '_myapp_session', :domain => :all
The :key option sets the name to use for the cookie, and :domain => :all says that the cookie can be shared across subdomains.
Now I want to move to using ActiveRecord to store the session. If I do this:
Myapp::Application.config.session_store :active_record_store
... although the session is stored in the database, there is still, of course, a cookie. But I no longer have control over its name or scope.
How can I use ActiveRecord store for the session and still specify the cookie name and domain?
Figured it out
It's very simple, actually:
Myapp::Application.config.session_store :active_record_store, :key => '_myapp_session', :domain => :all
My app's register and login processes take place on a secure subdomain. For this reason, I have modified config/initializers/session_store.rb to look like
if Rails.env.production?
AppName::Application.config.session_store :cookie_store, :key => '_app_name_session', :domain => '.app_name.com'
else
AppName::Application.config.session_store :cookie_store, :key => '_app_name_session'
end
so that the session can be shared across sub domains.
How can I share permanent cookies accross subdomains so that when I set a permanent cookie
on one subdomain via cookies.permanent[:some_key] = 'some value', I can access that cookie on another subdomain via cookies[:some_key]?
You need to specify the domain using a more verbose cookie setting method:
cookies[:some_cookie] = {
:value => "whatever",
:domain => ".app_name.com",
:expires => 1.year.from_now.utc
}
I haven't found a configuration setting to do this globally yet.
I'm trying to have cookies on my site dapshare.com work for both the root address and the 'www' subdomain.
A lot of other stackoverflow answers (and the great Railscasts vid on this topic) have suggested adding this line to session_store.rb:
Dapshare::Application.config.session_store :cookie_store, :key => '_dapshare_session', :domain => :all
This doesn't seem to make a difference: if I log in at dapshare.com, I still am not logged in at www.dapshare.com.
Am I doing something wrong here? I am using the following code to store information in the cookie:
cookies.permanent.signed[:thing_to_store] = store_information
Thanks for any help!
Short answer: using the 'cookies[:new_cookie] =' does not seem to grab the domain from the session_store config settings.
I added the :domain to the new cookie and it now works:
cookies.permanent.signed[:new_cookie] = {:value => new_value, :domain => ".dapshare.com"}
For anyone else reading, you also need to specify the domain when deleting the cookie
cookies.delete :new_cookie, :domain => ".dapshare.com"
(Thanks for your help with diagnosis Andrew Marshall.)
You can actually just specify your cookies using domain => :all instead of domain => '.dapshare.com' in Rails 3.1 +:
cookies.permanent.signed[:new_cookie] = {:value => new_value, :domain => :all}
This more flexible than outright specifying a string domain. Now your application won't break on a different production domain.
I encountered this issue, when passing :all doesn't seems to work properly. If you want to use only for subdomains try the following:
Dapshare::Application.config.session_store :cookie_store, :key => '_dapshare_session', :domain => '.dapshare.com'
I setup the cookie store to domain => :all, like I could find in documentation and it seems to work, because devise's authentication works across the multiple domain.
MyApp::Application.config.session_store :cookie_store, :key => '_MyApp.com_session', :domain => :all
However when I am trying myself to write to a cookie, it always write down the sub domain... I don't get it:
I write the cookie in the simplest manner possible:
cookies.permanent[:remember_locale] = locale
But no matter what it won't set it for the top level domain whereas the one dropped by devise seems to manage it without a problem :(
Alex
ps: I am using rails 3.0.3
The configuration for the session_store only applies to the session cookie. When setting a separate cookie you have to specify the domain for that cookie as well.
cookies.permanent[:remember_locale] = { :value => locale, :domain => :all }
Note (pulled from rails source):
# Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
#
# cookies[:key] = {
# :value => 'a yummy cookie',
# :expires => 1.year.from_now,
# :domain => 'domain.com'
# }
#
# cookies.delete(:key, :domain => 'domain.com')
I'm working on a fairly traditional forgot password email - I want to email the user a password change token embedded in a link that they can click on in order to change their password. I'm emailing via the traditional ActionMailer.
If I use a normal link_to tag
<%= link_to "click here", :controller => foo, :action => 'bar', :token => token %>
I get a relative link - rather useless from an email.
If I add in
:only_path => false, then it errors saying I need to set default_url_options[:host]. The ActionController docs imply that you do that by overriding the #default_url_options methods in your controller. Surely there's a configuration option to tell Rails what it's hostname is without adding my own config file, parsing it, etc?
default_url_options is available from config.action_mailer and should be set in your environment's configuration file.
For example, in config/environments/production.rb:
config.action_mailer.default_url_options = {
:host => 'www.yourdomain.com'
}
For local testing, modify config/environments/development.rb:
config.action_mailer.default_url_options = {
:host => '127.0.0.1',
:port => 3000
}
Then, assuming you have a named route called forgot_password_login, you can generate the login link URL in your mailer using something like this:
forgot_password_login_url(:token => 'a7s8q15sk2...')
You probably want to set :protocol => 'https' as well, btw.
config.action_mailer.default_url_options = {
:host => "portal.example.com",
:protocol => 'https'
}
There is another alternative, as described in http://pivotallabs.com/how-i-leaned-to-stop-hating-and-love-action-mailer/
This solution has the advantage that it doesn't require any configuration (so less of a hassle), and works fine as long as you send emails from within controllers.
But if you plan on sending email without going through a controller (e.g. from command line or in response to another email), you need the static configuration.
Setting default_url_options directly is deprecated in Rails 3.1. Use url_for instead.
Add parameter :protocol to override default value (http), :protocol => 'https://'. This will create url starting with "https://..." instead of default "http://"
Interestingly, I had the same issue as you did, but in unit tests (while following Michael Hartl's railstutorial). I had this line in my test.rb file, but that didn't help:
config.action_mailer.default_url_options = { host: 'example.com', protocol: 'http' }
I've also added another line like this to test.rb, and surprisingly this solved the issue
default_url_options = { host: 'example.com', protocol: 'http' }
Setting default_url_options directly is deprecated in Rails 3.1
Use the url_for helper to create it:
<%= link_to "click here", url_for(:controller => foo, :action => 'bar', :token => token, :host => 'www.yourdomain.com') %>
Can you just do
<%="click here", :controller => foo, :action => 'bar', :token => token, :host=>request.host -%>