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.
- data/README.rdoc +74 -0
- data/Rakefile +12 -0
- data/cookieless_sessions.gemspec +31 -0
- data/init.rb +1 -0
- data/lib/cookieless_sessions.rb +83 -0
- metadata +64 -0
data/README.rdoc
ADDED
@@ -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/]
|
data/Rakefile
ADDED
@@ -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
|
+
|