Django 中的身份验证和授权:Django 会话

Django Session 简介

在现代 Web 应用程序中,在多个请求中维护用户状态对于创建个性化体验至关重要。Django 通过其内置会话框架简化了此过程,使开发人员能够安全高效地管理用户数据。

Django 中的内置会话负责管理多个请求中的用户数据。当用户登录 Django 应用程序时,服务器会创建一个会话 ID,通常存储在客户端浏览器的 cookie 中。此会话 ID 用作检索存储在服务器上的数据并将请求链接到特定用户的密钥。这就是身份验证状态将在不同的页面上持续存在的原因。

在 Django 中使用会话中间件

Django 的会话中间件可自动执行会话管理。它处理传入请求以检索会话数据,并准备传出响应以更新或设置会话 cookie。要检查会话中间件是否已启用,请查看 MIDDLEWARE 部分下的“settings.py”文件:

# settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    # Other middleware
]

Django 中的会话存储类型

我们有多种保存会话数据的选项。根据您要构建的应用程序,每种选项都有优点和缺点。

1. 数据库支持的会话

**类比**:假设剧院有一个安全的储藏室,里面有储物柜,所有外套都存放在那里。每个储物柜都有一个唯一的编号,与你票上的号码相匹配。当你拿着票回来时,服务员会在日志中查找储物柜号码并取回你的外套。

数据库支持的会话将会话数据保存在数据库服务器上。因此,用户偏好、登录状态和购物车详细信息等敏感信息仍安全地保存在后端。这种类型的会话可能更安全,但在涉及写入和读取过程时会带来一些不便。与缓存支持的会话相比,数据库支持的会话速度较慢,因此如果您正在构建流量很大的应用程序,那么您应该再考虑一下。如果管理不善,将会话存储在数据库中会增加数据库的负载,影响整体性能。

如果您想使用数据库支持的会话,则需要将“django.contrib.sessions”添加到“INSTALLED_APPS”设置中。请确保运行“manage.py migration”以安装存储会话数据的单个数据库表。

2.基于文件的会话

**类比**:在这种情况下,每件外套都存放在剧院后面一个大房间里不同的带标签的储物柜中。每个储物柜都有一个独特的标签或文件,上面有外套的详细信息,当你出示你的票时,服务员会去更衣室,找到相应的标签,然后取回你的外套。

基于文件的会话使用服务器的文件系统来保存会话数据。这意味着每个用户会话都存储在服务器上的单独文件中。默认情况下,Django 将会话文件存储在 `/tmp` 下的 django_session 目录中(在基于 Unix 的系统上)或 Django 设置中指定的目录中。

要启用基于文件的会话,请在 settings.py 文件中将 `SESSION_ENGINE` 设置为 `django.contrib.sessions.backends.file`。

# settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.file'  # Use file-based session storage
SESSION_FILE_PATH = '/path/to/session/files/'  # Specify a directory for session files (optional)

3. 缓存支持的会话

**类比**:这里,剧院在入口附近使用了一个临时衣帽架,衣服只在那里存放很短的时间。这样可以快速取到衣服,但如果衣帽架满了,最旧的衣服可能会被移到二级存储或完全移走。

这种类型的会话存储是缓存系统(例如 Memcached 或 Redis)存储会话数据的地方。将会话保存在内存缓存中将有助于流量大或需要快速响应时间的应用程序,因为写入或读取过程非常迅速。

要使用缓存支持的会话,请在“settings.py”文件中配置“SESSION_ENGINE”设置。您还必须根据使用的缓存内存配置缓存。

# settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # For caching session storage
SESSION_CACHE_ALIAS = 'default'  # Specify the cache alias if needed (e.g., 'redis' or 'memcached')

# Cache configuration (example with Redis)
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',  # Redis URL
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        }
    }
}

或者,您可以使用“django.contrib.sessions.backends.cached_db”,它将会话数据同时存储在缓存和数据库中,如果缓存不可用,则回退到数据库。

使用这种会话类型的最大优势是可扩展性和速度。缓存支持的会话不仅速度快,因为将数据保存在内存中,而且还减少了数据库会话的负载,数据可以在服务器之间共享,从而实现多服务器设置。

4. 签名的 Cookie 会话

**类比**:在这里,剧院不会将您的外套存放在仓库中,而是允许您随身携带,但要求您在票上盖上特殊印章以验证这是您的外套。您随身携带外套(场次数据),每次您进入剧院时,服务员都会检查票上的印章以确保它没有被篡改。

Django 中的签名 cookie 会话将会话数据直接存储在客户端浏览器的签名和加密 cookie 中,而不是将其存储在服务器端(数据库或缓存)。

要启用签名的 cookie 会话,请在 Django 的 `settings.py` 文件中设置 `SESSION_ENGINE` 以使用签名的 cookie 后端:

# settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
SECRET_KEY = 'your-secret-key'  # Make sure this key is kept secure and unique for your app

签名 Cookie 会话可减少服务器负载并释放服务器资源。但是,由于 Cookie 的大小限制(大约 4 KB),签名 Cookie 会话不适合存储大量会话数据。较大的 Cookie 大小会导致请求速度变慢,因为每次请求都会发送 Cookie 数据。

会话配置设置

Django 提供了几个设置来配置会话行为:

  • SESSION_COOKIE_AGE:设置会话过期时间(以秒为单位)。
  • SESSION_COOKIE_SECURE:要求会话通过 HTTPS 传输。
  • SESSION_EXPIRE_AT_BROWSER_CLOSE:当浏览器关闭时结束会话。
  • SESSION_COOKIE_HTTPONLY:限制 JavaScript 对会话 cookie 的访问,增强安全性。
  • 这些设置有助于根据特定应用程序需求定制会话行为。有关会话配置的更多信息,请阅读 Django 文档。

    在 Django 视图中实现会话

    要与 Django 视图中的会话进行交互,请使用“request.session 对象”,其行为类似于字典。以下是一些基本操作:

    **存储数据:**

    request.session['username'] = 'Harry Potter'

    **正在检索数据:**

    username = request.session.get('username')

    **删除数据:**

    del request.session['username']

    会话的常见用途是跟踪用户登录状态。以下是使用会话实现简单登录系统的方法:

    # views.py
    from django.shortcuts import render, redirect
    from django.contrib.auth import authenticate, login
    
    def user_login(request):
        if request.method == 'POST':
            username = request.POST['username']
            password = request.POST['password']
            user = authenticate(request, username=username, password=password)
            if user:
                login(request, user)
                request.session['username'] = username  # Store session data
                return redirect('home')
            else:
                return render(request, 'login.html', {'error': 'Invalid login'})
        return render(request, 'login.html')

    Django 视图中仍有许多用于会话的方法。有关完整列表,请查看 Django 文档。

    会议最佳实践

    Django 会定期删除过期的会话。您可以通过配置会话清理过程或运行管理命令(如“django-admin clearsessions”)来自定义频率。

    避免在会话中存储大量数据,因为这可能会增加服务器负载并降低响应时间。最后启用安全的“cookie”、“HttpOnly”和“HTTPS 设置”来保护会话数据。

    结论

    Django 的会话框架功能强大、灵活且安全,可让您轻松在 Web 应用程序中实现会话管理。通过适当的配置和安全实践,您可以利用 Django 会话来创建高效、个性化的用户体验,同时保持强大的安全性。