tatyree-cookieless_sessions 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,74 @@
1
+ = Cookieless Sessions
2
+
3
+ A rails gem that brings together everything needed to enable cookieless sessions in rails.
4
+
5
+ Let's say you're developing a mobile phone site and cookie-based sessions just don't
6
+ work for a significant segment of your user base. There are various bits of code scattered
7
+ around, and at least one old gem for dealing with this. However, getting everything
8
+ together and working requires a good deal of monkey patching. That's where this gem
9
+ comes in: all the monkey patches together in one place.
10
+
11
+ == Install
12
+
13
+ gem install tatyree-cookieless_sessions --source http://gems.github.com
14
+
15
+ == Usage
16
+
17
+ First, you need to set up an alternative session store in environment.rb
18
+
19
+ config.action_controller.session_store = :mem_cache_store
20
+
21
+ We've only ever used it with the mem_cache_store, but there's no reason
22
+ that it shouldn't work with any other server-side store.
23
+
24
+ Next, require it in environment.rb after the Rails::Initializer block:
25
+
26
+ require 'cookieless_sessions'
27
+
28
+ Lastly, you need to add a before_filter to your ApplicationController
29
+ to check to see if cookies are enabled:
30
+
31
+ class ApplicationController < ActionController::Base
32
+ ...
33
+ before_filter :check_cookies
34
+
35
+ ...
36
+
37
+ protected
38
+
39
+ ...
40
+
41
+ def check_cookies
42
+ cookies[:_sessions] ||= { :value => 'true', :expires => 30.seconds.from_now } unless session[:cookies_off]
43
+
44
+ if cookies.blank?
45
+ logger.info "** Cookies appear to be disabled on this session."
46
+ session[:cookies_off] = true
47
+ end
48
+ end
49
+
50
+ I suggest that, once a session has been set as cookieless, you should not try to
51
+ change it back (i.e. <tt>else; session[:cookies_off] = false; end;</tt>). If you do,
52
+ the current session will be lost if cookie handling flip-flops.
53
+
54
+ You can customize this method as you see fit. Please note, however, that the gem
55
+ depends on the :cookies_off session key.
56
+
57
+ == Gotchas
58
+
59
+ There aren't very many. Variations of this have been running in production on several
60
+ of our apps for months now. The main thing to watch out for is phones that can't handle
61
+ GET and POST variables in the same request (which, if I'm honest, is a bit of a flakey
62
+ way to do it). Happily, they are becoming rare. The main symptom is a controller method
63
+ throwing exceptions because the only parameter it receives is the session_id: The phone
64
+ sees the query string on the form action and discards any other parameters. So far, I've
65
+ tried incorporating the session_id as a hidden variable in the form. This works fine for
66
+ passing the parameter, but getting the session handling code to pick it up, and selectively
67
+ excluding the query parameter from the form action url has proven very difficult.
68
+
69
+ == Credits
70
+
71
+ * {The original source of the main monkey patch}[http://dev.rubyonrails.org/ticket/10900]
72
+ * {Changing sessions options in rails}[http://wiki.rubyonrails.org/rails/pages/HowtoChangeSessionOptions]
73
+ * {The fatdrive.tv cookieless session plugin}[http://wiki.rubyonrails.org/rails/pages/HowtoChangeSessionOptions]
74
+ * {The original source of the default_url_options example}[http://brantinteractive.com/2008/05/13/cookieless-sessions-in-rails/]
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('cookieless_sessions', '0.1.0') do |p|
6
+ p.description = "Allow cookieless sessions in Rails."
7
+ p.url = "http://github.com/tatyree/cookieless_sessions"
8
+ p.author = "Todd Tyree"
9
+ p.email = "todd@snappl.co.uk"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = []
12
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{cookieless_sessions}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Todd Tyree"]
9
+ s.date = %q{2009-02-07}
10
+ s.description = %q{Allow cookieless sessions in Rails.}
11
+ s.email = %q{todd@snappl.co.uk}
12
+ s.extra_rdoc_files = ["lib/cookieless_sessions.rb", "README.rdoc"]
13
+ s.files = ["cookieless_sessions.gemspec", "init.rb", "lib/cookieless_sessions.rb", "Manifest", "Rakefile", "README.rdoc"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/tatyree/cookieless_sessions}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Cookieless_sessions", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{cookieless_sessions}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Allow cookieless sessions in Rails.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ else
28
+ end
29
+ else
30
+ end
31
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'cookieless_sessions'
@@ -0,0 +1,83 @@
1
+ module CookielessSessions
2
+ end
3
+
4
+ class ::CGI #:nodoc:
5
+ class Session #:nodoc:
6
+ alias_method :initialize_without_uri_session_key, :initialize
7
+
8
+ def initialize(cgi, options = {}, session_id=nil)
9
+ key = options['session_key']
10
+
11
+ if cgi.cookies[key].empty?
12
+ if !session_id
13
+ query = ENV['RAW_POST_DATA'] || cgi.query_string || ''
14
+ session_id = CGI.parse(query)[key].first if cgi.cookies[key].empty?
15
+ end
16
+ if session_id
17
+ cgi.params[key] = session_id
18
+ options['session_id'] = cgi.params[key]
19
+ end
20
+ end
21
+ @cgi = cgi
22
+ initialize_without_uri_session_key(cgi, options)
23
+ end
24
+ end
25
+ end
26
+
27
+ # These enable the cookieless sessions required by some mobile phones and operators.
28
+ ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:cookie_only] = false
29
+
30
+ module ActionController
31
+
32
+ class Base
33
+ # Technically, this is a protected method. However, if you make it protected here and use restful
34
+ # routes, then any route without parameters loses the session id. So, users_url(:id => 1) has the
35
+ # session_key added, but users_url and users_path do not.
36
+
37
+ # TODO: Some phones cannot handle GET and POST parameters in the same request. Ideally, it would be
38
+ # possible to prepend the session_key to the path, but this does not seem to be the case with routing
39
+ # as it stands.
40
+
41
+ # TODO: There ought to be a more elegant way of getting the session_key. The problem with other methods
42
+ # is that they do not pick up a custom key at initialization time.
43
+ def default_url_options(options = nil)
44
+ session_key = ApplicationController.session.first[:session_key].to_sym
45
+ { session_key => (request.xhr? ? params[session_key] : session.session_id) } if session[:cookies_off] == true
46
+ end
47
+ end
48
+
49
+ class CgiRequest
50
+ def session
51
+ unless defined?(@session)
52
+ if @session_options == false
53
+ @session = Hash.new
54
+ else
55
+ stale_session_check! do
56
+ if cookie_only? && query_parameters[session_options_with_string_keys['session_key']]
57
+ raise SessionFixationAttempt
58
+ end
59
+ case value = session_options_with_string_keys['new_session']
60
+ when true
61
+ @session = new_session
62
+ when false
63
+ begin
64
+ @session = CGI::Session.new(@cgi, session_options_with_string_keys, query_parameters[session_options_with_string_keys['session_key']])
65
+ # CGI::Session raises ArgumentError if 'new_session' == false
66
+ # and no session cookie or query param is present.
67
+ rescue ArgumentError
68
+ @session = Hash.new
69
+ end
70
+ when nil
71
+ @session = CGI::Session.new(@cgi, session_options_with_string_keys, query_parameters[session_options_with_string_keys['session_key']])
72
+ else
73
+ raise ArgumentError, "Invalid new_session option: #{value}"
74
+ end
75
+ @session['__valid_session']
76
+ end
77
+ end
78
+ end
79
+ @session
80
+ end
81
+ end
82
+ end
83
+
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tatyree-cookieless_sessions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Todd Tyree
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-07 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Allow cookieless sessions in Rails.
17
+ email: todd@snappl.co.uk
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/cookieless_sessions.rb
24
+ - README.rdoc
25
+ files:
26
+ - cookieless_sessions.gemspec
27
+ - init.rb
28
+ - lib/cookieless_sessions.rb
29
+ - Manifest
30
+ - Rakefile
31
+ - README.rdoc
32
+ has_rdoc: true
33
+ homepage: http://github.com/tatyree/cookieless_sessions
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --line-numbers
37
+ - --inline-source
38
+ - --title
39
+ - Cookieless_sessions
40
+ - --main
41
+ - README.rdoc
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "1.2"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project: cookieless_sessions
59
+ rubygems_version: 1.2.0
60
+ signing_key:
61
+ specification_version: 2
62
+ summary: Allow cookieless sessions in Rails.
63
+ test_files: []
64
+