authlogic-connect 0.0.3.9 → 0.0.4.03
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.markdown +9 -5
- data/Rakefile +7 -3
- data/lib/authlogic-connect.rb +2 -2
- data/lib/authlogic_connect/{token.rb → access_token.rb} +1 -1
- data/lib/authlogic_connect/authlogic_connect.rb +0 -0
- data/lib/authlogic_connect/common/session.rb +13 -10
- data/lib/authlogic_connect/common/state.rb +21 -5
- data/lib/authlogic_connect/common/user.rb +27 -65
- data/lib/authlogic_connect/common/variables.rb +75 -11
- data/lib/authlogic_connect/oauth/helper.rb +0 -0
- data/lib/authlogic_connect/oauth/process.rb +19 -12
- data/lib/authlogic_connect/oauth/session.rb +15 -11
- data/lib/authlogic_connect/oauth/state.rb +19 -13
- data/lib/authlogic_connect/oauth/tokens/aol_token.rb +2 -0
- data/lib/authlogic_connect/oauth/tokens/google_token.rb +11 -11
- data/lib/authlogic_connect/oauth/tokens/meetup_token.rb +12 -0
- data/lib/authlogic_connect/oauth/tokens/netflix_token.rb +10 -0
- data/lib/authlogic_connect/oauth/tokens/oauth_token.rb +6 -2
- data/lib/authlogic_connect/oauth/tokens/ohloh_token.rb +9 -0
- data/lib/authlogic_connect/oauth/user.rb +9 -14
- data/lib/authlogic_connect/oauth/variables.rb +9 -0
- data/lib/authlogic_connect/openid/process.rb +49 -5
- data/lib/authlogic_connect/openid/session.rb +13 -34
- data/lib/authlogic_connect/openid/state.rb +45 -44
- data/lib/authlogic_connect/openid/tokens/openid_token.rb +1 -1
- data/lib/authlogic_connect/openid/user.rb +5 -29
- data/lib/authlogic_connect/openid/variables.rb +2 -2
- data/lib/open_id_authentication.rb +0 -1
- data/test/controllers/test_users_controller.rb +0 -0
- data/test/libs/database.rb +0 -0
- data/test/libs/user.rb +6 -2
- data/test/libs/user_session.rb +0 -0
- data/test/test_helper.rb +1 -1
- data/test/test_user.rb +5 -66
- metadata +10 -6
data/README.markdown
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# AuthlogicConnect
|
2
2
|
|
3
|
-
AuthlogicConnect is an extension of the Authlogic library to add
|
3
|
+
AuthlogicConnect is an extension of the Authlogic library that aims to add complete and seamless Oauth and OpenID support to your application.
|
4
4
|
|
5
|
-
It allows you to login through any of the 30+ Oauth and OpenID providers on the Internet.
|
5
|
+
It allows you to login through any of the 30+ Oauth and OpenID providers on the Internet without having to write any of the logic yourself.
|
6
6
|
|
7
7
|
That makes life easy and gives you a lot of power.
|
8
8
|
|
@@ -32,7 +32,7 @@ AuthlogicConnect currently allows you to login with 7 Oauth providers and all th
|
|
32
32
|
- [OpenID Providers](http://en.wikipedia.org/wiki/List_of_OpenID_providers)
|
33
33
|
- [More OpenID](http://openid.net/get-an-openid/)
|
34
34
|
|
35
|
-
## Install
|
35
|
+
## Install
|
36
36
|
|
37
37
|
### 1. Install AuthlogicConnect
|
38
38
|
|
@@ -57,7 +57,7 @@ Rails 3: `Gemfile`
|
|
57
57
|
gem "oauth2"
|
58
58
|
gem "authlogic-connect"
|
59
59
|
|
60
|
-
### 3. Add the
|
60
|
+
### 3. Add the OpenIdAuthentication.store
|
61
61
|
|
62
62
|
Do to [some strange problem](http://github.com/openid/ruby-openid/issues#issue/1) I have yet to really understand, Rails 2.3.5 doesn't like when `OpenIdAuthentication.store` is null, which means it uses the "in memory" store and for some reason fails.
|
63
63
|
|
@@ -237,4 +237,8 @@ Thanks for the people that are already extending the project, all the input maki
|
|
237
237
|
|
238
238
|
Feel free to add to the wiki if you figure things out or make new distinctions.
|
239
239
|
|
240
|
-
|
240
|
+
## Flow
|
241
|
+
|
242
|
+
- Try to create a session
|
243
|
+
- Session logs into provider
|
244
|
+
- On success, if no user, redirect to User#create
|
data/Rakefile
CHANGED
@@ -6,11 +6,11 @@ require 'rake/gempackagetask'
|
|
6
6
|
spec = Gem::Specification.new do |s|
|
7
7
|
s.name = "authlogic-connect"
|
8
8
|
s.author = "Lance Pollard"
|
9
|
-
s.version = "0.0.
|
10
|
-
s.summary = "Authlogic Connect:
|
9
|
+
s.version = "0.0.4.03"
|
10
|
+
s.summary = "Authlogic Connect: Oauth and OpenID made dead simple"
|
11
11
|
s.homepage = "http://github.com/viatropos/authlogic-connect"
|
12
12
|
s.email = "lancejpollard@gmail.com"
|
13
|
-
s.description = "
|
13
|
+
s.description = "Oauth and OpenID made dead simple"
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.rubyforge_project = "authlogic-connect"
|
16
16
|
s.platform = Gem::Platform::RUBY
|
@@ -68,4 +68,8 @@ Rake::RDocTask.new do |rdoc|
|
|
68
68
|
rdoc.rdoc_files.add(files)
|
69
69
|
rdoc.main = "README.markdown"
|
70
70
|
rdoc.title = spec.summary
|
71
|
+
end
|
72
|
+
|
73
|
+
task :yank do
|
74
|
+
`gem yank #{spec.name} -v #{spec.version}`
|
71
75
|
end
|
data/lib/authlogic-connect.rb
CHANGED
@@ -11,13 +11,13 @@ require "#{this}/open_id_authentication"
|
|
11
11
|
require "#{library}/ext"
|
12
12
|
require "#{library}/authlogic_connect"
|
13
13
|
require "#{library}/callback_filter"
|
14
|
-
require "#{library}/
|
14
|
+
require "#{library}/access_token"
|
15
15
|
require "#{library}/openid"
|
16
16
|
require "#{library}/oauth"
|
17
17
|
require "#{library}/common"
|
18
18
|
require "#{library}/engine" if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
19
19
|
|
20
|
-
custom_models = ["#{library}/
|
20
|
+
custom_models = ["#{library}/access_token"]
|
21
21
|
custom_models += Dir["#{library}/oauth/tokens"]
|
22
22
|
custom_models += Dir["#{library}/openid/tokens"]
|
23
23
|
|
File without changes
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AuthlogicConnect::Common
|
2
2
|
module Session
|
3
3
|
|
4
|
-
def self.included(base)
|
4
|
+
def self.included(base)
|
5
5
|
base.class_eval do
|
6
6
|
include Variables
|
7
7
|
include InstanceMethods
|
@@ -10,18 +10,21 @@ module AuthlogicConnect::Common
|
|
10
10
|
|
11
11
|
module InstanceMethods
|
12
12
|
|
13
|
-
# core save method coordinating how to save the session
|
13
|
+
# core save method coordinating how to save the session.
|
14
|
+
# want to destroy the block if we redirect to a remote service, that's it.
|
15
|
+
# otherwise the block contains the render methods we wan to use
|
14
16
|
def save(&block)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
self.errors.clear
|
18
|
+
# log_state
|
19
|
+
authenticate_via_protocol(block_given?) do |redirecting|
|
20
|
+
block = nil if redirecting
|
21
|
+
result = super(&block)
|
22
|
+
cleanup_authentication_session unless block.nil?
|
23
|
+
result
|
20
24
|
end
|
21
|
-
block = nil if block_destroyed
|
22
|
-
super(&block)
|
23
25
|
end
|
26
|
+
|
24
27
|
end
|
25
28
|
|
26
29
|
end
|
27
|
-
end
|
30
|
+
end
|
@@ -1,16 +1,32 @@
|
|
1
1
|
# This class holds query/state variables common to oauth and openid
|
2
2
|
module AuthlogicConnect::Common::State
|
3
3
|
|
4
|
-
def
|
5
|
-
!
|
4
|
+
def auth_controller?
|
5
|
+
!auth_controller.blank?
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def auth_params?
|
9
|
-
!auth_params.blank?
|
9
|
+
auth_controller? && !auth_params.blank?
|
10
|
+
end
|
11
|
+
|
12
|
+
def auth_session?
|
13
|
+
!auth_session.blank?
|
10
14
|
end
|
11
15
|
|
12
16
|
def is_auth_session?
|
13
17
|
self.is_a?(Authlogic::Session::Base)
|
14
18
|
end
|
15
19
|
|
16
|
-
|
20
|
+
def start_authentication?
|
21
|
+
start_oauth? || start_openid?
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_password_with_oauth?
|
25
|
+
!using_openid? && super
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_password_with_openid?
|
29
|
+
!using_oauth? && super
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -14,18 +14,18 @@ module AuthlogicConnect::Common::User
|
|
14
14
|
|
15
15
|
def self.included(base)
|
16
16
|
base.class_eval do
|
17
|
-
has_many :
|
18
|
-
belongs_to :active_token, :class_name => "
|
19
|
-
accepts_nested_attributes_for :
|
17
|
+
has_many :access_tokens, :class_name => "AccessToken", :dependent => :destroy
|
18
|
+
belongs_to :active_token, :class_name => "AccessToken", :dependent => :destroy
|
19
|
+
accepts_nested_attributes_for :access_tokens, :active_token
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def authenticated_with
|
24
|
-
@authenticated_with ||= self.
|
24
|
+
@authenticated_with ||= self.access_tokens.collect{|t| t.service_name.to_s}
|
25
25
|
end
|
26
26
|
|
27
27
|
def authenticated_with?(service)
|
28
|
-
self.
|
28
|
+
self.access_tokens.detect{|t| t.service_name.to_s == service.to_s}
|
29
29
|
end
|
30
30
|
|
31
31
|
def update_attributes(attributes, &block)
|
@@ -38,7 +38,7 @@ module AuthlogicConnect::Common::User
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def get_token(service_name)
|
41
|
-
self.
|
41
|
+
self.access_tokens.detect {|i| i.service_name.to_s == service_name.to_s}
|
42
42
|
end
|
43
43
|
|
44
44
|
# core save method coordinating how to save the user.
|
@@ -46,68 +46,30 @@ module AuthlogicConnect::Common::User
|
|
46
46
|
# authentication mission we are trying to accomplish.
|
47
47
|
# instead, we just return save as false.
|
48
48
|
# the next time around, when we recieve the callback,
|
49
|
-
# we will run the validations
|
49
|
+
# we will run the validations.
|
50
|
+
# when you call 'current_user_session' in ApplicationController,
|
51
|
+
# it leads to calling 'save' on this User object via "session.record.save",
|
52
|
+
# from the 'persisting?' method. So we don't want any of this to occur
|
53
|
+
# when that save is called, and the only way to check currently is
|
54
|
+
# to check if there is a block_given?
|
50
55
|
def save(options = {}, &block)
|
51
|
-
|
56
|
+
self.errors.clear
|
57
|
+
# log_state
|
52
58
|
options = {} if options == false
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
# forces you to validate, maybe get rid of if needed,
|
57
|
-
# but everything depends on this
|
58
|
-
if ActiveRecord::VERSION::MAJOR < 3
|
59
|
-
result = super(true) # validate!
|
60
|
-
else
|
61
|
-
result = super(options.merge(:validate => true))
|
62
|
-
end
|
63
|
-
# debug_user_save_post
|
64
|
-
yield(result) if block_given? # give back to controller
|
59
|
+
options[:validate] = true unless options.has_key?(:validate)
|
60
|
+
save_options = ActiveRecord::VERSION::MAJOR < 3 ? options[:validate] : options
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# it only reaches this point once it has returned, or you
|
78
|
-
# have manually skipped the redirect and save was called directly.
|
79
|
-
def cleanup_auth_session
|
80
|
-
cleanup_oauth_session
|
81
|
-
cleanup_openid_session
|
82
|
-
end
|
83
|
-
|
84
|
-
def validate_password_with_oauth?
|
85
|
-
!using_openid? && super
|
86
|
-
end
|
87
|
-
|
88
|
-
def validate_password_with_openid?
|
89
|
-
!using_oauth? && super
|
90
|
-
end
|
91
|
-
|
92
|
-
# test methods for dev/debugging, commented out by default
|
93
|
-
def debug_user_save_pre(options = {}, &block)
|
94
|
-
puts "USER SAVE "
|
95
|
-
puts "block_given? #{block_given?.to_s}"
|
96
|
-
puts "using_oauth? #{using_oauth?.to_s}"
|
97
|
-
puts "using_openid? #{using_openid?.to_s}"
|
98
|
-
puts "authenticating_with_oauth? #{authenticating_with_oauth?.to_s}"
|
99
|
-
puts "authenticating_with_openid? #{authenticating_with_openid?.to_s}"
|
100
|
-
puts "validate_password_with_oauth? #{validate_password_with_oauth?.to_s}"
|
101
|
-
puts "validate_password_with_openid? #{validate_password_with_openid?.to_s}"
|
102
|
-
puts "!using_openid? && require_password? #{(!using_openid? && require_password?).to_s}"
|
103
|
-
end
|
104
|
-
|
105
|
-
def debug_user_save_post
|
106
|
-
puts "ERRORS: #{errors.full_messages}"
|
107
|
-
puts "using_oauth? #{using_oauth?.to_s}"
|
108
|
-
puts "using_openid? #{using_openid?.to_s}"
|
109
|
-
puts "validate_password_with_oauth? #{validate_password_with_oauth?.to_s}"
|
110
|
-
puts "validate_password_with_openid? #{validate_password_with_openid?.to_s}"
|
62
|
+
# kill the block if we're starting authentication
|
63
|
+
authenticate_via_protocol(block_given?, options) do |redirecting|
|
64
|
+
block = nil if redirecting
|
65
|
+
# forces you to validate, only if a block is given
|
66
|
+
result = super(save_options) # validate!
|
67
|
+
unless block.nil?
|
68
|
+
cleanup_authentication_session(options)
|
69
|
+
yield(result)
|
70
|
+
end
|
71
|
+
result
|
72
|
+
end
|
111
73
|
end
|
112
74
|
|
113
75
|
end
|
@@ -1,19 +1,18 @@
|
|
1
1
|
module AuthlogicConnect::Common::Variables
|
2
2
|
include AuthlogicConnect::Common::State
|
3
|
+
|
4
|
+
attr_reader :processing_authentication
|
3
5
|
|
4
|
-
def
|
5
|
-
is_auth_session? ?
|
6
|
+
def auth_class
|
7
|
+
is_auth_session? ? self.class : session_class
|
6
8
|
end
|
7
9
|
|
8
|
-
def
|
9
|
-
|
10
|
-
auth_controller.session.keys.each do |key|
|
11
|
-
auth_controller.session[key.to_s] = auth_controller.session.delete(key) if key.to_s =~ /^OpenID/
|
12
|
-
end
|
13
|
-
auth_controller.session
|
10
|
+
def auth_controller
|
11
|
+
is_auth_session? ? controller : session_class.controller
|
14
12
|
end
|
15
13
|
|
16
14
|
def auth_params
|
15
|
+
return nil unless auth_controller?
|
17
16
|
auth_controller.params.symbolize_keys!
|
18
17
|
auth_controller.params.keys.each do |key|
|
19
18
|
auth_controller.params[key.to_s] = auth_controller.params.delete(key) if key.to_s =~ /^OpenID/
|
@@ -21,6 +20,15 @@ module AuthlogicConnect::Common::Variables
|
|
21
20
|
auth_controller.params
|
22
21
|
end
|
23
22
|
|
23
|
+
def auth_session
|
24
|
+
return nil unless auth_controller?
|
25
|
+
auth_controller.session.symbolize_keys!
|
26
|
+
auth_controller.session.keys.each do |key|
|
27
|
+
auth_controller.session[key.to_s] = auth_controller.session.delete(key) if key.to_s =~ /^OpenID/
|
28
|
+
end
|
29
|
+
auth_controller.session
|
30
|
+
end
|
31
|
+
|
24
32
|
def auth_callback_url(options = {})
|
25
33
|
auth_controller.url_for({:controller => auth_controller.controller_name, :action => auth_controller.action_name}.merge(options))
|
26
34
|
end
|
@@ -31,10 +39,11 @@ module AuthlogicConnect::Common::Variables
|
|
31
39
|
end
|
32
40
|
|
33
41
|
# auth_params and auth_session attributes are all String!
|
34
|
-
def from_session_or_params(
|
35
|
-
|
42
|
+
def from_session_or_params(attribute)
|
43
|
+
return nil unless auth_controller?
|
44
|
+
key = attribute.is_a?(Symbol) ? attribute : attribute.to_sym
|
36
45
|
result = auth_params[key] if (auth_params && auth_params[key])
|
37
|
-
result = auth_session[key] if result.
|
46
|
+
result = auth_session[key] if (result.nil? || result.blank?)
|
38
47
|
result
|
39
48
|
end
|
40
49
|
|
@@ -42,6 +51,8 @@ module AuthlogicConnect::Common::Variables
|
|
42
51
|
# uncertain as to how they are saved. So this makes sure if we are
|
43
52
|
# logging in, it must be saving the session, otherwise the user.
|
44
53
|
def correct_request_class?
|
54
|
+
return false unless auth_params?
|
55
|
+
|
45
56
|
if is_auth_session?
|
46
57
|
auth_type.to_s == "session"
|
47
58
|
else
|
@@ -53,6 +64,55 @@ module AuthlogicConnect::Common::Variables
|
|
53
64
|
|
54
65
|
end
|
55
66
|
|
67
|
+
def remove_session_key(key)
|
68
|
+
keys = key.is_a?(Symbol) ? [key, key.to_s] : [key, key.to_sym]
|
69
|
+
keys.each {|k| auth_session.delete(k)}
|
70
|
+
end
|
71
|
+
|
72
|
+
# wraps the call to "save" (in yield).
|
73
|
+
# reason being, we need to somehow not allow oauth/openid validations to run
|
74
|
+
# when we don't have a block. We can't know that using class methods, so we create
|
75
|
+
# this property "processing_authentication", which is used in the validation method.
|
76
|
+
# it's value is set to "block_given", which is the value of block_given?
|
77
|
+
def authenticate_via_protocol(block_given = false, options = {}, &block)
|
78
|
+
@processing_authentication = auth_controller? && block_given
|
79
|
+
saved = yield start_authentication?
|
80
|
+
@processing_authentication = false
|
81
|
+
saved
|
82
|
+
end
|
83
|
+
|
84
|
+
# returns boolean
|
85
|
+
def authentication_protocol(with, phase)
|
86
|
+
returning(send("#{phase.to_s}_#{with.to_s}?")) do |ready|
|
87
|
+
send("#{phase.to_s}_#{with.to_s}") if ready
|
88
|
+
end if send("using_#{with.to_s}?")
|
89
|
+
end
|
90
|
+
|
91
|
+
# it only reaches this point once it has returned, or you
|
92
|
+
# have manually skipped the redirect and save was called directly.
|
93
|
+
def cleanup_authentication_session(options = {}, &block)
|
94
|
+
unless (options.has_key?(:keep_session) && options[:keep_session])
|
95
|
+
%w(oauth openid).each do |type|
|
96
|
+
send("cleanup_#{type.to_s}_session")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def log(*methods)
|
102
|
+
methods.each do |method|
|
103
|
+
puts "#{method.to_s}: #{send(method).inspect}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def log_state
|
108
|
+
log(:correct_request_class?)
|
109
|
+
log(:using_oauth?, :start_oauth?, :complete_oauth?)
|
110
|
+
log(:oauth_request?, :oauth_response?, :stored_oauth_token_and_secret?)
|
111
|
+
log(:using_openid?, :start_openid?, :complete_openid?, :openid_request?, :openid_response?)
|
112
|
+
log(:authenticating_with_openid?)
|
113
|
+
log(:stored_oauth_token_and_secret)
|
114
|
+
end
|
115
|
+
|
56
116
|
# because we may need to store 6+ session variables, all with pretty lengthy names,
|
57
117
|
# might as well just tinify them.
|
58
118
|
# just an idea
|
@@ -70,4 +130,8 @@ module AuthlogicConnect::Common::Variables
|
|
70
130
|
@optimized_session_keys[key]
|
71
131
|
end
|
72
132
|
|
133
|
+
def auto_register?
|
134
|
+
true
|
135
|
+
end
|
136
|
+
|
73
137
|
end
|
File without changes
|
@@ -4,15 +4,13 @@ module AuthlogicConnect::Oauth::Process
|
|
4
4
|
|
5
5
|
# Step 2: after save is called, it runs this method for validation
|
6
6
|
def validate_by_oauth
|
7
|
-
|
8
|
-
|
9
|
-
restore_attributes
|
10
|
-
complete_oauth_transaction
|
7
|
+
if processing_authentication
|
8
|
+
authentication_protocol(:oauth, :start) || authentication_protocol(:oauth, :complete)
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
14
12
|
# Step 3: if new_oauth_request?, redirect to oauth provider
|
15
|
-
def
|
13
|
+
def start_oauth
|
16
14
|
save_oauth_session
|
17
15
|
authorize_url = token_class.authorize_url(auth_callback_url) do |request_token|
|
18
16
|
save_auth_session_token(request_token) # only for oauth version 1
|
@@ -20,6 +18,17 @@ module AuthlogicConnect::Oauth::Process
|
|
20
18
|
auth_controller.redirect_to authorize_url
|
21
19
|
end
|
22
20
|
|
21
|
+
# Step 4: on callback, run this method
|
22
|
+
def complete_oauth
|
23
|
+
# implemented in User and Session Oauth modules
|
24
|
+
unless new_oauth_request? # shouldn't be validating if it's redirecting...
|
25
|
+
restore_attributes
|
26
|
+
complete_oauth_transaction
|
27
|
+
return true
|
28
|
+
end
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
|
23
32
|
# Step 3a: save our passed-parameters into the session,
|
24
33
|
# so we can retrieve them after the redirect calls back
|
25
34
|
def save_oauth_session
|
@@ -45,11 +54,6 @@ module AuthlogicConnect::Oauth::Process
|
|
45
54
|
def restore_attributes
|
46
55
|
end
|
47
56
|
|
48
|
-
# Step 4: on callback, run this method
|
49
|
-
def authenticate_with_oauth
|
50
|
-
# implemented in User and Session Oauth modules
|
51
|
-
end
|
52
|
-
|
53
57
|
# Step last, after the response
|
54
58
|
# having lots of trouble testing logging and out multiple times,
|
55
59
|
# so there needs to be a solid way to know when a user has messed up loggin in.
|
@@ -61,8 +65,11 @@ module AuthlogicConnect::Oauth::Process
|
|
61
65
|
:oauth_provider,
|
62
66
|
:auth_callback_method,
|
63
67
|
:oauth_request_token,
|
64
|
-
:oauth_request_token_secret
|
65
|
-
|
68
|
+
:oauth_request_token_secret,
|
69
|
+
:_key,
|
70
|
+
:_token,
|
71
|
+
:_secret,
|
72
|
+
].each {|key| remove_session_key(key)}
|
66
73
|
end
|
67
74
|
|
68
75
|
end
|