1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Attempt to coerce the generated_at cookie to a Time object.

Time objects aren't properly coerced back when using the JSON cookie serialization,
so we need to do it ourselves.

To avoid any new JSON serialization issues, we now store the `generated_at` as
an String with the timestamp seconds + miliseconds in the cookie but still the
previous JSON encoded format.

Thanks to @boblail at https://github.com/plataformatec/devise/pull/3917 for the
initial patch.
This commit is contained in:
Lucas Mazza 2016-01-28 15:01:06 -02:00
parent 475599d4ab
commit 7bff3be869
2 changed files with 24 additions and 2 deletions

View file

@ -97,6 +97,12 @@ module Devise
end
def remember_me?(token, generated_at)
# TODO: Normalize the JSON type coercion along with the Timeoutable hook
# in a single place https://github.com/plataformatec/devise/blob/ffe9d6d406e79108cf32a2c6a1d0b3828849c40b/lib/devise/hooks/timeoutable.rb#L14-L18
if generated_at.is_a?(String)
generated_at = time_from_json(generated_at)
end
# The token is only valid if:
# 1. we have a date
# 2. the current time does not pass the expiry period
@ -109,10 +115,20 @@ module Devise
Devise.secure_compare(rememberable_value, token)
end
private
def time_from_json(value)
if value =~ /\A\d+\.\d+\Z/
Time.at(value.to_f)
else
Time.parse(value) rescue nil
end
end
module ClassMethods
# Create the cookie key using the record id and remember_token
def serialize_into_cookie(record)
[record.to_key, record.rememberable_value, Time.now.utc]
[record.to_key, record.rememberable_value, Time.now.utc.to_f.to_s]
end
# Recreate the user based on the stored cookie

View file

@ -37,7 +37,7 @@ class RememberableTest < ActiveSupport::TestCase
id, token, date = User.serialize_into_cookie(user)
assert_equal id, user.to_key
assert_equal token, user.authenticatable_salt
assert date.is_a?(Time)
assert date.is_a?(String)
end
test 'serialize from cookie' do
@ -46,6 +46,12 @@ class RememberableTest < ActiveSupport::TestCase
assert_equal user, User.serialize_from_cookie(user.to_key, user.authenticatable_salt, Time.now.utc)
end
test 'serialize from cookie should accept a String with the datetime seconds and microseconds' do
user = create_user
user.remember_me!
assert_equal user, User.serialize_from_cookie(user.to_key, user.authenticatable_salt, Time.now.utc.to_f.to_json)
end
test 'serialize from cookie should return nil with invalid datetime' do
user = create_user
user.remember_me!