HTTP是一种无状态协议,每次请求是没有关联性的,
即客户端请求完之后,再次请求,服务器就不记得客户端了。
如果需要实现类似登录,这种有状态的场景,就需要有一种机制来记录客户端状态。
例如,在客户端登录成功的情况下,才能访问某些页面。
Session就是用来记录这种状态的。
Session是一段保存在服务器端的字符串。该字符串记录了客户端的状态。
Cookie和Session类似,只不过Cookie保存在客户端中。
注意:该实现过程只是为了说清楚原理,细节部分并不一定准确
登录:
Session超时:(用户登录后不操作,Session超时则需要重新登录)
登出:
django.contrib.sessions.backends.cache.SessionStore
(取决于session存储位置)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()
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'
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')
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'),
]