django session key changing upon authentication

2020-08-13 04:55发布

问题:

I have a Django app which records users' product choices for both authenticated users. My intention is to use the request.session.session_key variable to associate anonymous data with a user if they decide to register later, a la this post:

Django storing anonymous user data

However, it seems that the session key changes when the user logs in/ registers so the session key can no longer be associated with the user. Is this the correct behaviour of the Django session framework. Is there a solid way to achieve the functionality I'm looking for?

Any help much appreciated.

回答1:

In settings.py

SESSION_ENGINE = 'youapp.session_backend'

in directory youapp in file session_backend.py

from django.contrib.sessions.backends.db import SessionStore as DbSessionStore

class SessionStore(DbSessionStore):
    def cycle_key(self):
        pass

And session not changed after login



回答2:

While the approach suggested by nnmware may work for this particular case, there is a better one.

Instead of just doing nothing inside cycle_key, we should call the super method and then save the session.

Because if you look inside the original cycle_key function you will see that the data from the old session is copied to the new one, but is not actually saved.

In settings.py

SESSION_ENGINE = 'yourapp.session_backend'

Check that SESSION_ENGINE is pointing at a module (.py file), but not to the backend class!

Now, in your 'yourapp/session_backend.py' do the following:

from django.contrib.sessions.backends.db import SessionStore as DbSessionStore

class SessionStore(DbSessionStore):
    def cycle_key(self):
        super(SessionStore, self).cycle_key()
        self.save()


回答3:

One of the solutions would also be to update old session data in the Session store:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.contrib.sessions.backends.db import SessionStore as DbSessionStore
from shop.models.cart import Cart


class SessionStore(DbSessionStore):
    def cycle_key(self):
        old_session_key = super(SessionStore, self).session_key
        super(SessionStore, self).cycle_key()
        self.save()
        Cart.objects.filter(session_key=old_session_key).update(session_key=self.session_key)