Saving session variables at login

I want to store user settings information in a session variable. If the user selects a preference when logging out and then logs in, I want the preference to be maintained without having to re-select it.

Django classes maintain a session key in a cookie to track user sessions. As I understand it, this key changes when the user logs in.

a) Does this mean that all session variables are deleted at the entrance to the system or is there any passage

b) If it is not possible to save preferences during login, the cookie is set manually in the best way to continue? I imagine a scenario like:

  • when logging out, save the settings in a cookie
  • when logging in, copy preferences into the session variable and write to db (via signal?)
  • when logging out, update your cookies with settings (via a signal?)

Update

I managed to get this functionality by saving preferences in the user profile object as well as in the cookie (these settings are in no way sensitive). When a user logs in, preference is given to setting up a profile. If you are not logged in, cookie preference is selected.

+2
source share
5 answers

When logging in / out, Django will clear all sessions if another user logs in (request.session.flush () in auth / init .py).

, .

+2

Django session.flush() session.cycle_key(), , . , . , , , , .

- , , .

Chase Seibert , - . , :

class persist_session_vars(object):
    """
    Some views, such as login and logout, will reset all session state.
    (via a call to ``request.session.cycle_key()`` or ``session.flush()``).
    That is a security measure to mitigate session fixation vulnerabilities.

    By applying this decorator, some values are retained.
    Be very aware what find of variables you want to persist.
    """

    def __init__(self, vars):
        self.vars = vars

    def __call__(self, view_func):

        @wraps(view_func)
        def inner(request, *args, **kwargs):
            # Backup first
            session_backup = {}
            for var in self.vars:
                try:
                    session_backup[var] = request.session[var]
                except KeyError:
                    pass

            # Call the original view
            response = view_func(request, *args, **kwargs)

            # Restore variables in the new session
            for var, value in session_backup.items():
                request.session[var] = value

            return response

        return inner

:

from django.contrib.auth import views

@persist_session_vars(['some_field'])
def login(request, *args, **kwargs):
    return views.login(request, *args, **kwargs)

(django-allauth):

import allauth.account.views as auth_views
from django.utils.decorators import method_decorator

@method_decorator(persist_session_vars(['some_field']), name='dispatch')
class LoginView(auth_views.LoginView):
    pass

URL:

import allauth.urls
from django.conf.urls import include, url

from . import views

urlpatterns = [
    # Views that overlap the default:
    url(r'^login/$', views.LoginView.as_view(), name='account_login'),

    # default allauth urls
    url(r'', include(allauth.urls)),
]
+5

, , , - UserProfile model

+1

, . /, - .

from functools import wraps

class persist_session_vars(object):
    """ Some views, such as login and logout, will reset all session state.
    However, we occasionally want to persist some of those session variables.
    """

    session_backup = {}

    def __init__(self, vars):
        self.vars = vars

    def __enter__(self):
        for var in self.vars:
            self.session_backup[var] = self.request.session.get(var)

    def __exit__(self, exc_type, exc_value, traceback):
        for var in self.vars:
            self.request.session[var] = self.session_backup.get(var)

    def __call__(self, test_func, *args, **kwargs):

        @wraps(test_func)
        def inner(*args, **kwargs):
            if not args:
                raise Exception('Must decorate a view, ie a function taking request as the first parameter')
            self.request = args[0]
            with self:
                return test_func(*args, **kwargs)

        return inner

, auth.login/logout. , .

from django.contrib.auth import views

@persist_session_vars(['HTTP_REFERER'])
def login(request, *args, **kwargs):
    return views.login(request, *args, **kwargs)
0
source

You can create a Mixin form that allows you to save the form values ​​in a user session (which does not require their login). This is useful for things like filtering / sorting options in an open report on the table view in which you want their filter settings to be saved when updating.

filter form screenshot

View:

def list_states(request):
    if request.method == 'GET':
        form = StateListFilterForm().load_from_session(request.session)
    elif request.method == 'POST':
        form = StateListFilterForm(request.POST)
        form.persist_to_session()
    return render('forms/state_list.html', RequestContext(request, {'state_form': form})

the form:

class PersistableMixin:
    def persist_to_session(form, session):
        for key in form.fields.keys():
            val = getattr(form, 'cleaned_data', form.data).get(key, None)
            if val:  # will not store empty str values
                session[key] = val
        return True

    def load_from_session(form, session):
        for key in form.fields.keys():
            saved_val = session.get(key, '')
            if saved_val:  # will not load empty str values
                form.fields[key].initial = saved_val
        return form


class StateListFilterForm(forms.Form, PersistableMixin):
    states = forms.MultipleChoiceField(required=False, choices=US_STATES)
0
source

All Articles