Git Product home page Git Product logo

django-qsessions's Introduction

Django QSessions

pypi tests ci coverage MIT black

django-qsessions offers two extended session backends for Django. They extend Django's db and cached_db backends (and Session model) with following extra features:

  • Sessions have a foreign key to User
  • Sessions store IP and User Agent

These features help you implement "Session Management" and show a list of active sessions to the user. You can display IP, location and user agent for each session and add an option to revoke sessions.

Comparison

Here is a brief comparison between Django's session backends (db, cache, cached_db), and django-qsessions.

django qsessions
cache db cached_db db cached_db
Performance ✔✔
Persistence
Foreign Key to User
Store IP and User Agent

Compatibility

  • Python: 3.8, 3.9, 3.10, 3.11, 3.12
  • Django: 4.2, 5.0

Installation

If your system is in production and there are active sessions using another session backend, you need to migrate them manually. We have no migration script.

  1. If you want to use the cached_db backend, make sure you've configured your cache. If you have multiple caches defined in CACHES, Django will use the default cache. To use another cache, set SESSION_CACHE_ALIAS to the name of that cache.

  2. Install the latest version from PyPI:

    pip install django-qsessions
  3. In settings:

    • In INSTALLED_APPS replace 'django.contrib.sessions' with 'qsessions'.
    • In MIDDLEWARE or MIDDLEWARE_CLASSES replace 'django.contrib.sessions.middleware.SessionMiddleware' with 'qsessions.middleware.SessionMiddleware'.
    • Set SESSION_ENGINE to:
      • 'qsessions.backends.cached_db' if you want to use cached_db backend.
      • 'qsessions.backends.db' if you want to use db backend.
  4. Run migrations to create qsessions.models.Session model.

    python manage.py migrate qsessions

To enable location detection using GeoIP2 (optional):

  1. Install geoip2 package:

    pip install geoip2
  2. Set GEOIP_PATH to a directory for storing GeoIP2 database.

  3. Run the following command to download latest GeoIP2 database. You can add this command to a cron job to update GeoIP2 DB automatically. Due to Maxmind license changes you will need to acquire and use a license key for downloading the databases. You can pass the key on the command line, or in the MAXMIND_LICENSE_KEY environment variable.

    python manage.py download_geoip_db -k mykey

Usage

django-qsessions has a custom Session model with following extra fields: user, user_agent, created_at, updated_at, ip.

Get a user's sessions:

user.session_set.filter(expire_date__gt=timezone.now())

Delete a session:

# Deletes the session from both the database and the cache.
session.delete()

Logout a user:

user.session_set.all().delete()

Get session creation time (user login time):

>>> session.created_at
datetime.datetime(2018, 6, 12, 17, 9, 17, 443909, tzinfo=<UTC>)

Get IP and user agent:

>>> session.ip
'127.0.0.1'
>>> session.user_agent
'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36'

Get user device (parsed user-agent string):

>>> str(session.device())
'K / Android 10 / Chrome Mobile 118.0.0'
>>> session.device().device
Device(family='K', brand='Generic_Android', model='K')
>>> session.device().os
OperatingSystem(family='Android', version=(10,), version_string='10')
>>> session.device().browser
Browser(family='Chrome Mobile', version=(118, 0, 0), version_string='118.0.0')

And if you have configured GeoIP2, you can get location info using .location() and .location_info():

>>> session.location()
'Tehran, Iran'

>>> session.location_info()
{'city': 'Tehran', 'continent_code': 'AS', 'continent_name': 'Asia', 'country_code': 'IR', 'country_name': 'Iran', 'time_zone': 'Asia/Tehran', ...}

Admin page:

image

Caveats

  • session.updated_at is not the session's exact last activity. It's updated each time the session object in DB is saved. (e.g. when user logs in, or when ip, user agent, or session data changes)

Why not django-user-sessions?

django-user-sessions has the same functionality, but only extends the db backend. Using a cache can improve performance.

We got ideas and some codes from django-user-sessions. Many thanks to Bouke Haarsma for writing django-user-sessions.

Development

  • Create and activate a python virtualenv.
  • Install development dependencies in your virtualenv with pip install -e '.[dev]'
  • Install pre-commit hooks with pre-commit install
  • Run tests with coverage:
    • py.test --cov

TODO

  • Write better documentation.
    • Explain how it works (in summary)
    • Add more details to existing documentation.
  • Write more tests
  • Performance benchmark (and compare with Django's cached_db)

Contributions are welcome!

License

MIT

django-qsessions's People

Contributors

akx avatar ataylor32 avatar danialkeimasi avatar jayvdb avatar mjnaderi avatar willstott101 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-qsessions's Issues

Drop drepecated ipware API

django-ipware has just released version 3.0.0.

In this version they have dropped some methods already deprecated in version 2.x. Among those there are both get_real_ip and get_ip which are being replaced by get_client_ip.

Unfotunatelly this breaks SessionMiddleware in this library, thus making django.contrib.admin checks fail with code admin.E410:

?: (admin.E410) 'django.contrib.sessions.middleware.SessionMiddleware' must be in MIDDLEWARE in order
 to use the admin application.

from ipware.ip import get_real_ip, get_ip

It should be released a new version using the most recent API of ipware and pinning at least django-ipware>=2.0.0.

Provide a non-cached backend too?

According to the official Django docs there is little benefit to using a cached session back-end unless you're using memcached - an unnecessary complication in many deployments.

It would be really nice for us if we could choose a single dependency for extended sessions without having to make the cached/un-cached decision at the same time. Not to mention it would make profiling the two options much much easier.

Especially as django-user-sessions has so little activity from it's maintainers. Would you consider merging a PR which adds a non-cached db back-end?

binascii.Error: Incorrect padding

This occurred when loading /admin/ on Django 2.2. Note I am using django-lockdown , and I have switched between Django 3.0 and 2.2 using the same sqlite db, which might have triggered this, and why it doesnt occur when I re-try it on Django 3.1.

Traceback (most recent call last):
  File "django/contrib/sessions/backends/base.py", line 189, in _get_session
    return self._session_cache
AttributeError: 'SessionStore' object has no attribute '_session_cache'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "lockdown/middleware.py", line 73, in __call__
    response = self.process_request(request)
  File "lockdown/middleware.py", line 172, in process_request
    token = session.get(self.session_key)
  File "django/contrib/sessions/backends/base.py", line 65, in get
    return self._session.get(key, default)
  File "django/contrib/sessions/backends/base.py", line 194, in _get_session
    self._session_cache = self.load()
  File "qsessions/backends/db.py", line 25, in load
    data = super().load()
  File "django/contrib/sessions/backends/cached_db.py", line 37, in load
    data = self.decode(s.session_data)
  File "django/contrib/sessions/backends/base.py", line 100, in decode
    encoded_data = base64.b64decode(session_data.encode('ascii'))
  File "base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

Provide a way to detected IP/user_agent changes

I took a look at your code and I think that would be very useful to implement detection of IP or user agent changes during a session: this could be indicative of a session hijacking attempt.
There is something similar implemented/in your roadmap?
Thank you!

Install Qsessions

I received this error when I want to build docker-compose through the command docker-compose build:

Collecting django-qsessions==1.1.0 (from -r /root/requirements.txt (line 18))
  Downloading https://files.pythonhosted.org/packages/5d/d1/198912d3740a6ffe9820ad229c239e3f4ef912e4b4baaf7d261f027a22eb/django-qsessions-1.1.0.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-xnld3yme/django-qsessions/setup.py", line 5, in <module>
        README = readme.read()
      File "/usr/lib/python3.6/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1423: ordinal not in range(128)
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-xnld3yme/django-qsessions/
ERROR: Service 'web' failed to build: The command '/bin/sh -c pip install -r /root/requirements.txt' returned a non-zero code: 1                                                                            

Is there any solution for this issue?!

Possible solution

Django 5.x compatibility?

Has anyone tested django-qsessions on the current release of Django?

Is it okay if I'd make a pull request to have tests run on Django 5.0?

Add a configurable verbose_name to apps.py

Having the app appear in Django's admin interface as "Qsessions" could be confusing for some users. It's fine if that's the default, but it would be nice if it was able to be configured to be "Sessions" or "User Logins" or whatever will be easiest for a particular project's users to understand.

DRF support

It would be nice if the user for DRF sessions are linked in qsessions.

Django 2.2 compatibility

Hey there,

Just wanted to let you know there are a couple compatibility issues with Qsessions and the freshly released Django 2.2. I've raised a couple of tickets over at the Django bug tracker:

Session may be extended indefinitely

Since qsessions uses a custom session object which is altered every time User-Agent or IP change there is a side-effect due to how base Django session engine works.

Upon save session engine changes expiry date by calling get_expiry_date (which without any arguments just extends session duration by its maximum length).

If, by any reason, a user with an active session changes User-Agent (ie: automatic updates) or IP (ie: dynamic IP) more frequently than configured session duration the session will never expire since it is saved upon every change.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.