pallets-eco / flask-session

Server side session extension for Flask
https://flask-session.readthedocs.io
BSD 3-Clause "New" or "Revised" License
488 stars 236 forks source link

TypeError: Encoding objects of type LazyString is unsupported #230

Closed alisharify7 closed 3 months ago

alisharify7 commented 3 months ago

error

data in session(redis) session-data

hi, when I upgraded flask-session to version 0.8.0 this error occurred I think it is a bug or a conflict with other packages(flask-wtf-> csrf)

and when I downgraded flask-session, the issue was solved

Lxstr commented 3 months ago

hi @alisharify7 which version downgrade fixed it for you? I have changed the serializer away from pickle so this is likely due to the type of string being saved to session. It may be the csrf token or it may be something you are adding to session. Do you have any unusual strings like LazyString

Lxstr commented 3 months ago

Also which wtf package and version are you using

Lxstr commented 3 months ago

I can't see any issues testing with wtf on my end. I think it may be what you are trying to add to session?

alisharify7 commented 3 months ago

My flask-wtf version is 1.2.1 When I downgraded Flask-session to version 0.6.0 problem was solved

maybe the problem was for flask-babel.lazy_gettext function

I have some views in my code like the below that uses _l function

  from flask_babel import lazy_gettext as _l

  flash(_l('done'), "success")

  session.pop("allow-set-password")
  session.pop("mail")
  session.pop("raw-token")
Lxstr commented 3 months ago

ok yes this is definitely the issue. Msgspec is not able to serialize this type whereas pickle in 0.6 could. I will run some tests with it. In the mean time if you like you can try using SESSION_SERIALIZATION_FORMAT="json" there's a small chance that might work.

Lxstr commented 3 months ago

@alisharify7 Msgspec only directly supports subclasses of list, tuple, and dict. LazyString is a subclass of object. I could go into either seeing if that class could be created differently or using enc_hook but I think the easiest solution would be cast to string before you flash (which passes to session)

flash(str(_l('done'), "success"))

Would that work for you?

alisharify7 commented 3 months ago

@alisharify7 Msgspec only directly supports subclasses of list, tuple, and dict. LazyString is a subclass of object. I could go into either seeing if that class could be created differently or using enc_hook but I think the easiest solution would be cast to string before you flash (which passes to session)

flash(str(_l('done'), "success"))

Would that work for you?

yes if I cast it to string before flashing it works, but it's not better flask-session itself do this? with an if or isinstance I think it can be solved under the hood

like:

if not isinstance(this, that):
   pass
if type(that)  ==  type(this):
    pass
Lxstr commented 3 months ago

I'm not sure, it would be changing the behaviour of your object without the developer realising.

Or, we could have a warning built into the setter of session, but the error message you do get is already pretty accurate.

I don't really like either option that much. I think I will leave this open for now and add further documentation on the serializer and make it easy to switch to other serializers.

Any more ideas or input on this is welcome.