Django3.0 Sessions使用示例

文章目录

  • 1. 简介
    • 1.1. 什么是Session
    • 1.2. 什么是Cookie
    • 1.3. 实现过程
  • 2. Session在Django中的存储位置
  • 3. 对象类型
  • 4. 函数说明
  • 5. 使用普通缓存settings.py配置
  • 6. view.py的编写
  • 7. urls.py配置


1. 简介

1.1. 什么是Session

HTTP是一种无状态协议,每次请求是没有关联性的,
即客户端请求完之后,再次请求,服务器就不记得客户端了。

如果需要实现类似登录,这种有状态的场景,就需要有一种机制来记录客户端状态。
例如,在客户端登录成功的情况下,才能访问某些页面。

Session就是用来记录这种状态的。

Session是一段保存在服务器端的字符串。该字符串记录了客户端的状态。

1.2. 什么是Cookie

Cookie和Session类似,只不过Cookie保存在客户端中。

1.3. 实现过程

注意:该实现过程只是为了说清楚原理,细节部分并不一定准确

登录:

  1. 客户端向服务器发出登录请求
  2. 服务器验证登录合法
  3. 服务器生成一段字符串(Session)保存起来
  4. 服务器将字符串(Session)打包在响应中发给客户端
  5. 客户端收到响应后将字符串(Cookie)取出保存起来
  6. 客户端向服务器请求登录后能看到的其他页面,并将字符串(Cookie)打包在内
  7. 服务器收到请求后将字符串(Cookie)取出,与原先保存的字符串(Session)对比
  8. 服务器字符串对比成功,服务器给出响应

Session超时:(用户登录后不操作,Session超时则需要重新登录)

  1. Session超时,服务器清除Session
  2. 客户端请求登录以后才能访问的页面
  3. 服务器中Session已被清除,认为客户端未认证,返回登录页面

登出:

  1. 客户端主动发送登出
  2. 服务器收到请求后,清除Session

2. Session在Django中的存储位置

  • 存在数据库中(默认)
  • 存在普通缓存中
  • 存在高速缓存中
  • 存在文件中
  • 只在Cookie中

3. 对象类型

  1. request:
  2. request.session:django.contrib.sessions.backends.cache.SessionStore(取决于session存储位置)

4. 函数说明

from django.contrib.auth import login, logout, authenticate
# 检测登录信息
authenticate()
# 将Session标记为登录状态
login()
# 将Session标记为登出状态
logout()

# 重置Session的超时时间
# django.contrib.sessions.backends.cache.SessionStore.set_expiry()
request.session.set_expiry()

5. 使用普通缓存settings.py配置

INSTALLED_APPS = [
    # 自己的app
    'test.apps.CachetestConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    # Django 默认安装了Session APP
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    # Django 默认启动了Seesion中间件
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # Django 3.0已弃用
    # 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# Session引擎,使用普通缓存保存Session,不配置将存在默认的数据库中
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

6. view.py的编写

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.views.generic import View

overtime = 600

# 认证检测类
class Auth(View):
    # 重写父类dispatch,加入认证功能
    def dispatch(self, request, *args, **kwargs):
        # 如果已认证
        if request.user.is_authenticated:
            # 当有页面操作时,重置超时时间(600秒)
            request.session.set_expiry(overtime)
            # 认证成功调用父类方法,分配请求
            return super().dispatch(request, *args, **kwargs)
        # 还没认证重定向到登录界面
        else:
            return redirect('test:login') 

# 登录类
class Login(View):
    # 用户发送get请求,返回登录界面
    def get(self, request):
        return render(request, 'test/login.html')
    
    # 用户发送post请求,登录认证
    def post(self, request):
        # 获取用户名和密码
        username = request.POST['username']
        password = request.POST['password']
        # 使用admin的表检测用户信息
        user = authenticate(request, username=username, password=password)
        # 如果检测成功则返回用户名
        if user is not None:
            # 标记Session为登录
            login(request, user)
            # 重置Session过期时间(600秒后过期)
            request.session.set_expiry(overtime)
            # 返回登录后的页面给用户
            return redirect('test:index')
        # 如果检测失败,调用get,返回登录界面
        else:
            self.get(request)

# 登录后的类,继承认证检测类
class Index(Auth):
    def get(self, request):
        return render(request, 'test/index.html')

# 登出类,继承认证检测类(用户没登录怎么登出)
class Logout(Auth):
    def get(self, request):
        # 将Session标记为登出
        logout(request)
        # 返回登录界面
        return redirect('test:login')

7. urls.py配置

from django.urls import path

from . import views

app_name = 'test'

urlpatterns = [
    path('', views.Login.as_view(), name = 'login'), 
    path('index.html', views.Index.as_view(), name = 'index'),
    path('logout.html', views.Logout.as_view(), name = 'logout'),
]

你可能感兴趣的:(Django)