mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Decouple serializers from Devise modules. You can use any serializer at any time, as long the API required by the serializer is satisfied. Since session serializer is encrypted, it simply stores the id and the resource klass. Cookie is not encrypted, so it creates a random token and store it in the database, so in order to do the token cleanup, you need provide remember_me! and forget_me! methods, as in :rememberable.
This commit is contained in:
parent
a3e7ea59ae
commit
f26e6a269f
10 changed files with 95 additions and 71 deletions
|
@ -35,7 +35,7 @@ module Devise
|
||||||
}
|
}
|
||||||
|
|
||||||
STRATEGIES = [:authenticatable]
|
STRATEGIES = [:authenticatable]
|
||||||
SERIALIZERS = [:authenticatable, :rememberable]
|
SERIALIZERS = [:session, :cookie]
|
||||||
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
||||||
|
|
||||||
# Maps the messages types that are used in flash message. This array is not
|
# Maps the messages types that are used in flash message. This array is not
|
||||||
|
@ -166,6 +166,9 @@ rescue
|
||||||
require 'warden'
|
require 'warden'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set the default_scope to nil, so it's overwritten when the first route is declared.
|
# Clear some Warden default configuration which will be overwritten
|
||||||
|
Warden::Strategies.clear!
|
||||||
|
Warden::Serializers.clear!
|
||||||
Warden::Manager.default_scope = nil
|
Warden::Manager.default_scope = nil
|
||||||
|
|
||||||
require 'devise/rails'
|
require 'devise/rails'
|
|
@ -4,7 +4,7 @@ module Devise
|
||||||
autoload :Confirmable, 'devise/models/confirmable'
|
autoload :Confirmable, 'devise/models/confirmable'
|
||||||
autoload :Recoverable, 'devise/models/recoverable'
|
autoload :Recoverable, 'devise/models/recoverable'
|
||||||
autoload :Rememberable, 'devise/models/rememberable'
|
autoload :Rememberable, 'devise/models/rememberable'
|
||||||
autoload :SessionSerializer, 'devise/models/authenticatable'
|
autoload :SessionSerializer, 'devise/models/session_serializer'
|
||||||
autoload :Timeoutable, 'devise/models/timeoutable'
|
autoload :Timeoutable, 'devise/models/timeoutable'
|
||||||
autoload :Trackable, 'devise/models/trackable'
|
autoload :Trackable, 'devise/models/trackable'
|
||||||
autoload :Validatable, 'devise/models/validatable'
|
autoload :Validatable, 'devise/models/validatable'
|
||||||
|
|
|
@ -1,22 +1,8 @@
|
||||||
require 'devise/strategies/authenticatable'
|
require 'devise/strategies/authenticatable'
|
||||||
require 'devise/serializers/authenticatable'
|
require 'devise/models/session_serializer'
|
||||||
|
|
||||||
module Devise
|
module Devise
|
||||||
module Models
|
module Models
|
||||||
module SessionSerializer
|
|
||||||
# Hook to serialize user into session. Overwrite if you want.
|
|
||||||
def serialize_into_session(record)
|
|
||||||
[record.class, record.id]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Hook to serialize user from session. Overwrite if you want.
|
|
||||||
def serialize_from_session(keys)
|
|
||||||
klass, id = keys
|
|
||||||
raise "#{self} cannot serialize from #{klass} session since it's not its ancestors" unless klass <= self
|
|
||||||
klass.find(:first, :conditions => { :id => id })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Authenticable Module, responsible for encrypting password and validating
|
# Authenticable Module, responsible for encrypting password and validating
|
||||||
# authenticity of a user while signing in.
|
# authenticity of a user while signing in.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
require 'digest/sha1'
|
require 'devise/serializers/cookie'
|
||||||
require 'devise/serializers/rememberable'
|
|
||||||
|
|
||||||
module Devise
|
module Devise
|
||||||
module Models
|
module Models
|
||||||
|
|
19
lib/devise/models/session_serializer.rb
Normal file
19
lib/devise/models/session_serializer.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
require 'devise/serializers/session'
|
||||||
|
|
||||||
|
module Devise
|
||||||
|
module Models
|
||||||
|
module SessionSerializer
|
||||||
|
# Hook to serialize user into session. Overwrite if you want.
|
||||||
|
def serialize_into_session(record)
|
||||||
|
[record.class, record.id]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Hook to serialize user from session. Overwrite if you want.
|
||||||
|
def serialize_from_session(keys)
|
||||||
|
klass, id = keys
|
||||||
|
raise "#{self} cannot serialize from #{klass} session since it's not one of its ancestors" unless klass <= self
|
||||||
|
klass.find(:first, :conditions => { :id => id })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,11 +0,0 @@
|
||||||
require 'devise/serializers/base'
|
|
||||||
|
|
||||||
module Devise
|
|
||||||
module Serializers
|
|
||||||
class Authenticatable < Warden::Serializers::Session
|
|
||||||
include Devise::Serializers::Base
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Warden::Serializers.add(:authenticatable, Devise::Serializers::Authenticatable)
|
|
|
@ -7,24 +7,17 @@ module Devise
|
||||||
attr_reader :scope
|
attr_reader :scope
|
||||||
|
|
||||||
def serialize(record)
|
def serialize(record)
|
||||||
record.class.send(:"serialize_into_#{serialization_type}", record)
|
record.class.send(:"serialize_into_#{klass_type}", record)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deserialize(keys)
|
def deserialize(keys)
|
||||||
mapping.to.send(:"serialize_from_#{serialization_type}", keys)
|
mapping.to.send(:"serialize_from_#{klass_type}", keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch(scope)
|
def fetch(scope)
|
||||||
@scope = scope
|
@scope = scope
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialization_type
|
|
||||||
@serialization_type ||= begin
|
|
||||||
warden = self.class.ancestors.find{ |k| k < Warden::Serializers::Base && k != self.class }
|
|
||||||
warden.name.split("::").last.underscore
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
43
lib/devise/serializers/cookie.rb
Normal file
43
lib/devise/serializers/cookie.rb
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
require 'devise/serializers/base'
|
||||||
|
|
||||||
|
module Devise
|
||||||
|
module Serializers
|
||||||
|
# This is a cookie serializer which stores the information if a :remember_me
|
||||||
|
# is sent in the params and if the model responds to remember_me! as well.
|
||||||
|
# As in Session serializer, the invoked methods are:
|
||||||
|
#
|
||||||
|
# User.serialize_into_cookie(@user)
|
||||||
|
# User.serialize_from_cookie(*args)
|
||||||
|
#
|
||||||
|
# An implementation for such methods can be found at Devise::Models::Rememberable.
|
||||||
|
#
|
||||||
|
# Differently from session, this approach is based in a token which is stored in
|
||||||
|
# the database. So if you want to sign out all clients at once, you just need to
|
||||||
|
# clean up the token column.
|
||||||
|
#
|
||||||
|
class Cookie < Warden::Serializers::Cookie
|
||||||
|
include Devise::Serializers::Base
|
||||||
|
|
||||||
|
def store(record, scope)
|
||||||
|
remember_me = params[scope].try(:fetch, :remember_me, nil)
|
||||||
|
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
||||||
|
record.remember_me!
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_options(record)
|
||||||
|
super.merge!(:expires => record.remember_expires_at)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(scope, record=nil)
|
||||||
|
if record && record.respond_to?(:forget_me!)
|
||||||
|
record.forget_me!
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Warden::Serializers.add(:cookie, Devise::Serializers::Cookie)
|
|
@ -1,30 +0,0 @@
|
||||||
require 'devise/serializers/base'
|
|
||||||
|
|
||||||
module Devise
|
|
||||||
module Serializers
|
|
||||||
class Rememberable < Warden::Serializers::Cookie
|
|
||||||
include Devise::Serializers::Base
|
|
||||||
|
|
||||||
def store(record, scope)
|
|
||||||
remember_me = params[scope].try(:fetch, :remember_me, nil)
|
|
||||||
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
|
||||||
record.remember_me!
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_options(record)
|
|
||||||
super.merge!(:expires => record.remember_expires_at)
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete(scope, record=nil)
|
|
||||||
if record && record.respond_to?(:forget_me!)
|
|
||||||
record.forget_me!
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Warden::Serializers.add(:rememberable, Devise::Serializers::Rememberable)
|
|
22
lib/devise/serializers/session.rb
Normal file
22
lib/devise/serializers/session.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
require 'devise/serializers/base'
|
||||||
|
|
||||||
|
module Devise
|
||||||
|
module Serializers
|
||||||
|
# This serializer stores sign in information in th client session. It just
|
||||||
|
# extends Warden own serializer to move all the serialization logic to a
|
||||||
|
# class. For example, if a @user resource is given, it will call the following
|
||||||
|
# two methods to serialize and deserialize a record:
|
||||||
|
#
|
||||||
|
# User.serialize_into_session(@user)
|
||||||
|
# User.serialize_from_session(*args)
|
||||||
|
#
|
||||||
|
# This can be used any strategy and the default implementation is available
|
||||||
|
# at Devise::Models::SessionSerializer.
|
||||||
|
#
|
||||||
|
class Session < Warden::Serializers::Session
|
||||||
|
include Devise::Serializers::Base
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Warden::Serializers.add(:session, Devise::Serializers::Session)
|
Loading…
Reference in a new issue