简体   繁体   中英

Django Sessions not Working

I have built an application that shows users their storage usage and quotas on a system. Since there are many users, sifting through their storage allocations can be tedious so I want to give admins the option of acting as that user. The application decides which user is accessing the application based on an employee ID received via a secure badg, the variable (EMPLOYEE_ID) is stored in the request.META dictionary.

Ideally, I want the admins to be able to override this employee ID with another user's ID by posting it in a form. The form works and then serves the storage_home.html page as the employee the admin wishes to act as via a POST request, but when I or another admin clicks and does a GET for the quotas, the request.session dictionary is empty!

EMPLOYEE_ID is the original employee id of the admin
SIM_EMPLOYEE_ID is the employee the admin wishes to act as

I wonder if it's the way I'm linking to the quotas view in the storage_home.html template? Not sure.

Here is my code, I believe you should only need views, and the template that calls the quotas view function to see what the issue is since the request.sessions dictionary does have the SIM_EMPLOYEE_ID variable after the post that serves storage_home.html. I've omitted some variables from the views that are used in the template, but they work just fine, didn't want to clutter the code too much.

The sim_user function is called when the form is submitted. This then just recalls the storage function and right now successfully displays what I want it to, it's the GET request subsequently that fail to keep the session. I also have the following set in my settings:

SESSION_COOKIE_SECURE = True
SESSION_COOKIE_DOMAIN = '.mydomain.com'
SESSION_SAVE_EVERY_REQUEST = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = False

views.py

def home(request):
    """Redirect requests at root url to /storage"""

    return HttpResponseRedirect('/storage/')

def storage(request):
    """Return the home template."""

    context = {}
    context.update(csrf(request))

    empid = request.session.get('SIM_EMPLOYEE_ID')
    if not empid:
        empid = request.META.get('EMPLOYEE_ID')

    if functions.is_admin(empid):
        form = UserForm()
        context['form'] = form
        template = loader.get_template('storage_admin.html')
    else:
        template = loader.get_template('storage_home.html')

    data = RequestContext(request, context)
    return HttpResponse(template.render(data))

def sim_user(request):
    context = {}
    context.update(csrf(request))

    if request.method == 'POST':
        form = UserForm(request.POST)
        if form.is_valid():
            empid = form.cleaned_data['empid']
            request.session['SIM_EMPLOYEE_ID'] = empid
            request.session.modified = True
            return storage(request)

    template = loader.get_template('deny.html')
    data = RequestContext(request, context)
    return HttpResponse(template.render(data))

def quotas(request, sitename):
    """Return quota page depending on the
       id of the employee. If employee is an
       administrator, show all the quota information
       for all users/projects. If employee is a user
       of the sitename, show them user specific quota information.
       Otherwise, deny access and display a custom template."""

    context = {}
    site = sitename.capitalize()

    # EMPLOYEE_ID is in the Http Request's META information
    empid = request.session.get('SIM_EMPLOYEE_ID')
    if not empid:
        empid = request.META.get('EMPLOYEE_ID')

    if not empid:
        template = loader.get_template('deny.html')
        return HttpResponse(template.render(RequestContext(request, context)))

    if functions.is_admin(empid):
        template = loader.get_template('all_quotas.html')
    else:
        template = loader.get_template('personal_quotas.html')

    data = RequestContext(request, context)
    return HttpResponse(template.render(data))

storage_home.html

{% extends 'base.html' %}

{% block title %}Storage Utilization{% endblock %}

{% block content %}
    <h1 id="header"><b>Storage Utilization</b></h1>
    <p></p>
    <table id="storage_table" cellspacing="15">
        <tbody>
        {% for site in sites %}
        {% url "su.views.quotas" as quota %}
        <tr>
            <td><a href="{{ quota }}{{ site }}/"><img src="/static/images/{{ site }}.png"></a></td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
    <br></br>
{% endblock %}

Thanks for any help, please let me know if you need more explanation, code, or simplification.

Turns out removing SESSION_COOKIE_SECURE = True fixed the issue. This is my fault for not forgetting that my dev environment uses http and prod https. I actually have separate settings files, but failed to use them properly when I went back to test this new feature. I believe setting the SESSION_COOKIE_SECURE to True when using https should work once I test the production server.

Django provided session stopped working for me for some reason. I made my own it's really easy:

models.py

class CustomSession(models.Model):
    uid = models.CharField(max_length=256)

    def __str__(self):
        return self.uid

How to work with CustomSession

from oauth.models import CustomSession
session = CustomSession.objects      # get a list of session objects
new_user = CustomSession(uid=<UID>)  # save a user to the session (by uid)
session.get(id=<ID>).uid                 # get user id
session.get(id=<ID>).delete()           # delete user from session (logout)
session.all().delete()               # delete all user data in session

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM