-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Devise + Mongoid store wrong data in session #2882
Conversation
Hrm, this is very weird. Why is mongoid returning such a weird object on |
After some studies:
After that I've create ugly hack that do what is needed:
|
You should really consider using Appraisal for your tests (as Devise is Rails specific). |
This is very weird. Active Model specifies that the value returned by |
Appraisal is nice but in this case all you need to do is |
Mongoid |
What happens if you just call |
As my fix showed, |
Hrm... I just noticed it actually needs to get the first element of the array out. :( That's very specific to Mongoid and we would probably need to move it to the adapter instead then. |
After some thought it maybe look better as |
Despite your patch, the same problem appear using Devise + Mongoid 4.0.0 beta1 + Rails 4.1 rc1. |
when i entered email and password: Moped::Errors::QueryFailure in Admin::ProjectsController#index The operation: #<Moped::Protocol::Query @Length=124 @request_id=6 @response_to=0 @op_code=2004 @flags=[] @full_collection_name="mystand_development.users" @Skip=0 @limit=-1 @selector={"$query"=>{"_id"=>{"$oid"=>BSON::ObjectId('534513085533310d78000000')}}, "$orderby"=>{:_id=>1}} @fields=nil> failed with error 17287: "Can't canonicalize query: BadValue unknown operator: $oid" See https://github.com/mongodb/mongo/blob/master/docs/errors.md for details about this error. flash: {"discard"=>["alert"], "flashes"=>{"alert"=>"You need to sign in or sign up before continuing.", "notice"=>"Signed in successfully."}} |
If you want to work with Devise, mongoid and rails 4.1 while this is being worked on add the following to your user model:
The .to_s on the key resolves mongoid's BSON::ObjectId problem. Let me know if you want this as a pull request, an extra to_s on an active_record key should not break stuff I guess (have not tested that) |
That's an issue with the json cookies serializer of rails 4.1. See it here: |
I'm experiencing the same problem. For know I will implement the solution proposed by @ahmeij . When a final patch would be launched, I would be thankful if someone could notify me on comments. |
@ahmeij Your solution inspired me a lot. However, it doesn't fully solve the problem. I followed your solution and got the sign_in worked but I came up with this solution, it works perfectly for me. You guys can give a try:
Note: This solution only works with mongoid ~> 4.0.0. I will try to make a better patch which works with all version of |
@tranvictor your solution solve my problem, thanks |
Any progress on this? |
@tranvictor I was having the same issues as you, but I found a little tweak of your code worked well: class << self
def serialize_from_session(key, salt)
record = to_adapter.get(key[0].to_param)
record if record && record.authenticatable_salt == salt
end
end |
I have no idea what else this will break, but a workaround thats having promise for me is this on the user model.
It's just calling to_s on the id, as mongoid lets you query that way or via the BSON::Id object it returns. I have no idea how this may effect other libraries though. |
@thisbeluke your solution fixed the problem for me. Thanks! 👍 |
@StewartLSmith, same here. @thisbeluke solution worked when testing, but didn't work in the development environment, on the other hand @tranvictor solution worked when in development, but when testing with rspec it failed with:
I solved it using an horrible if elsif statement in devises ' user model, checking for both environments and now both works. But I hope this get solved soon :) |
This will be addressed in newer versions of Mongoid. For now, you can add the following in your model to solve the problem: def to_key
if key = super
key = key.map(&:to_s)
end
key
end |
defining id as a String could be a solution class User
include Mongoid::Document
field :_id, type: String
end |
@timoschilling would that affect mongodb performance? I know that they use BSON for performance so using String instead of BSON would have a side effect right? |
@tranvictor there is a small performance impact, how large it is depend on your collection size and your relation count. But that impact should not be a problem |
@arthurnn @timoschilling - None of these suggestions seem to be working at this point. I'm trying to get the
The libraries in question:
Thank you. |
Do you use a Model like this: class User
include Mongoid::Document
field :_id, type: String
end Is long time ago that I use Mongo, and I don't have access to a project with it, but in my mind the query should look like this: @selector={"$query"=>{"_id"=>"544cc81966756b699c000000"}, "$orderby"=>{:_id=>1}} |
@timoschilling Yeah, my model is in fact a
Note the additional |
@liquid and the |
@timoschilling yeah that's what i thought too. Never mind, I've disabled the JSON cookie serialised as per #2949 (comment) - I'm planning on using this as part of a pure JSON API anyway. Thank you for the quick responses anyway, greatly appreciated. Here's a 🍰 in return of your help. :)))) |
The cake is lie. Dnia 26 paź 2014 o godz. 18:59 Attila Györffy [email protected] napisał(a):
|
any updates on this?
@tranvictor I added these, it worked but now, our tests are failing, I think in our test sign_in (devise testhelper in Devise::TestHelpers is not working) |
the proposed hack by @ahmeij and @tranvictor worked fine for me except when I choose the "remember me" option then the same error appear when retrieving the user from the cookie. so I also changed the def self.serialize_from_session(key, salt)
record = to_adapter.get(key[0]["$oid"])
record if record && record.authenticatable_salt == salt
end
def self.serialize_from_cookie(id, remember_token)
record = to_adapter.get(id[0]["$oid"])
record if record && !record.remember_expired? &&
Devise.secure_compare(record.rememberable_value, remember_token)
end |
@sahin I also got the same problem with testing using May be we should create a new issue for this? |
I used this hack: # config/initializers/ext/bson.rb
module BSON
class ObjectId
def to_json(*args)
return to_s if args.blank?
args[0].generate(to_s)
end
alias :as_json :to_json
end
end |
@tranvictor's solution worked for me with Rails 4.1.5, Mongoid 4.0.0 and Devise 3.4. Thanks a lot! User.rb def self.serialize_from_session(key, salt)
record = to_adapter.get(key[0]["$oid"])
record if record && record.authenticatable_salt == salt
end key (extracted from In my case, just this method is good enough for all |
Devise + Mongoid store wrong data in session
❤️ |
`to_key` method on ActiveModel and ActiveRecord returns an key that can be can be used to query the db to find that object. We should follow that API, and not return an ObjectId object. This fixes an annoying bug when using Mongoid + Devise, where devise use the to_key method to serialize the user in the session. [related heartcombo/devise#2882] [fixes #3626]
Just fixed this bug on Mongoid side mongoid/mongoid@658a5d4 , it will be included in the next release , 4.0.2 |
@arthurnn any specific date on when 4.0.2 will be released? |
@almnes , soon, probably today or tomorrow. |
Ping for a 4.0.2 release. :) |
Obrigado! José Valimwww.plataformatec.com.br |
I know I'm late to the party here but just wanted to say thanks to everyone on this thread, I have a case where I have some data migrated from Postgres and therefore some records with integer IDs and other with ObjectID IDs, the information here helped me put together this little hack that fixed my problem, on my def self.serialize_from_session(key, salt)
record = to_adapter.get(key[0])
record ||= to_adapter.get(key[0].to_i)
record if record && record.authenticatable_salt == salt
end |
I'm using Devise 3.2.3 + Mongoid 4.0.0.beta1 and when I try to call
current_user
I get:Bug is somewhere where this is set: