http协议四大特性
- 基于TCP/IP作用于应用层的协议
- 基于请求响应
- 无状态: 同一个客户端发送多次请求没有任何关联
- 无连接
会话跟踪技术
多次请求之间记录消息来弥补http无状态保存的缺点(使多次请求有联系)、
- cookie
具体一个浏览器针对一个服务器存储其消息的键值对(key=value)
- 客户端-服务端
客户端第一次访问服务端的某一个功能,比如login功能,一开始客户端的请求头里是带着空字典去访问的,访问成功后,服务器后生成一个cookie给到客户端,比如说下面的cookie:
Cookie: BAIDUID=F00480318ED42C27C35D3A2FBE2B0AD7:FG=1; BIDUPSID=F00480318ED42C27C35D3A2FBE2B0AD7; PSTM=1561713680; BD_UPN=123253; BDUSS=npyYVNyVEMwaldpTUxBV1BCUlhBfmVRTGZJclFlaENWQ0tDeGJyVFQ3a09rRnBkSVFBQUFBJCQAAAAAAAAAAAEAAABYUcuESmF2YV93aW5uZXIyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4DM10OAzNdf; BD_HOME=1; H_PS_PSSID=26525_1453_21121_29522_29518_28518_29098_28838_29071
当客户端再次去访问的时候,客户端就带着这个味cookie来访问,服务器就判定了这个客户端访问过该功能,则不再生成cookie,直接让客户端访问其功能
cookie一旦生成,每次访问都会带着,除非失效,cookie是存在磁盘上的
访问不同的web服务的cookie是不同的,不同客户端访问同一个web服务的cookie也是不同的
-
session
保存在服务端上的键值对
服务端产生随机的串儿返回给客户端,服务端找一个地方将串儿与对应的信息存起来{'随机字符串':'敏感信息'}
客户端第一次骑牛携带的cookie:{}
服务器设置session: Request.session['username']='yuan' 设置session实现了3步
- 生成随机字符串 123ghrjsdg
- 把这次给浏览器的响应体里设置set_cookie, key是sessionid,值就是生成的随机字符串 123ghrjsdg
- 在django-session表中添加记录, session-key 是生成的随机字符串 123ghrjsdg,session-data是 {'username':'yuan'}
客户端第二次请求携带的cookie: {sessionid=123ghrjsdg}到某一个视图函数(访问某个功能)
服务器中的视图函数取session request.session['username'] 实现了3步
- 客户端携带着cookie: {sessionid=123ghrjsdg}, 视图函数会先读取到cookie中的随机字符串 123ghrjsdg
- 然后视图函数会去django-session表中找到session-key为cookie中的随机字符串 123ghrjsdg的记录
- 然后从这条记录中找到{'username':'yuan'},从而取出值,如果视图函数是登入功能的话,就可以判定这个发请求来的客户端登录成功了,而且登录名字是yuan
没有cookie,session没有任何存在的意义,当我们在浏览器上禁用了cookie,我们就无法登陆京东或者淘宝,因为服务器并没有session,验证无法通过,就无法登入了,session的查看方式在console下的application下的cookies可以查看
设置cookie
cookie语法
响应体: HttpResponse() ,render(), redirect()
设置cookie必须用响应体设置 obj.set_cookie(key,value)
设置完cookie,可以在响应头中查看 request.COOKIE.get(key) / request.COOKIE[key]
cookie超时时间: max_age(ie不支持), expires(ie支持,支持时间对象)
如果不设置超时时间,cookie就远生效
有效路径(path): 针对哪些路径下的视图函数能取到设置的cookie
代码验证
models.py
from django.db import models
class Userinfo(models.Model):
user=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
数据库测试数据
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^index/', views.index),
]
views.py
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
from app01.models import Userinfo
def login(request):
if request.method == 'POST':
user = request.POST.get('user')
pwd = request.POST.get('pwd')
s_user = Userinfo.objects.filter(user=user, pwd=pwd).first()
print(s_user.user, s_user.pwd)
if s_user:
# 登录成功
response = HttpResponse('登录成功')
response.set_cookie('name', s_user.user)
response.set_cookie('pwd', s_user.pwd, path='/index/')
# 设置用户的上次访问时间
import datetime
now = datetime.datetime.now().strftime('%Y-%m-%d %X')
response.set_cookie('now', now)
return response
else:
# 登录失败
pass
return render(request, 'login.html')
def index(request):
print('index', request.COOKIES)
name = request.COOKIES.get('name')
now = request.COOKIES.get('now', "")
if name:
return render(request, 'index.html', locals())
return redirect('/login/')
def test(request):
print('test', request.COOKIES)
return HttpResponse('test')
login.html
<body>
<form action="" method="post">
{% csrf_token %}
用户名 <input type="text" name="user">
密码 <input type="text" name="pwd">
<input type="submit" value="submit">
</form>
</body>
index.html
<body>
<h1>hi {{ name }}</h1>
</body>
当用户访问http://127.0.0.1:8000/login/,如果验证通过,则登录成功,成功返回设置的cookies,以及可以看到返回的消息
当浏览器输入网址http://127.0.0.1:8000/index/,可以查看到在login视图函数中设置的cookies
当浏览器输入网址http://127.0.0.1:8000/test/,不可以查看login函数中设置的pwd这个cookies
案例
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^reg/', views.reg),
url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^home/', views.home),
url(r'^xxx/', views.xxx),
]
views.py
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'lyysb' and password == '123':
old_path = request.GET.get('next')
if old_path:
obj = redirect(old_path)
else:
obj = redirect('/home/')
# 用户登录成功 朝浏览器设置一个cookie
obj.set_cookie('name', 'lyysb')
# 设置上次访问时间
import datetime
now = datetime.datetime.now().strftime('%Y-%m-%d %X')
obj.set_cookie('time', now)
return obj
return render(request, 'login.html')
from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request, *args, **kwargs):
print(request.get_full_path())
old_path = request.get_full_path()
# 校验cookie
if request.COOKIES.get('name'):
return func(request, *args, **kwargs)
return redirect('/login/?next=%s' % old_path)
return inner
@login_auth
def index(request):
# print(request.COOKIES.get('name'))
# if request.COOKIES.get('name'):
last_time = request.COOKIES.get('time',"")
return render(request, 'index.html', {'last_time': last_time})
@login_auth
def home(request):
return HttpResponse('我是home页面,只有登陆了才能看')
@login_auth
def xxx(request):
return HttpResponse('我是xxx页面,只有登陆了才能看')
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
<script
src="http://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
</head>
<body>
<form action="" method="post">
<p>username<input type="text" name="username"></p>
<p>password<input type="text" name="password"></p>
<input type="submit">
</form>
</body>
</html>
index.html
<body>
<h1>index</h1>
<p>上次访问时间:{{ last_time }}</p>
</body>`
设置Session
session语法
- 设置Sessions值 request.session['session_name']='admin'
- 获取Session值 session_name=request.session['session_name']
- 删除Session值 del request.session['session_name']
- Flush() 删除当前的会话数据并删除会话的Cookie 这用于确保前面的会话数据不可以再次被用户的浏览器访问
代码验证
models.py
from django.db import models
class Userinfo(models.Model):
user=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
数据库测试数据
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^login_session/', views.login_session),
url(r'^index_session/', views.index_session),
]
views.py
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
from app01.models import Userinfo
def login_session(request):
if request.method == 'POST':
user = request.POST.get('user')
pwd = request.POST.get('pwd')
user = Userinfo.objects.filter(user=user, pwd=pwd).first()
if user:
request.session['is_login'] = True
request.session['username'] = 'hppsb'
import datetime
now = datetime.datetime.now().strftime('%Y-%m-%d %X')
request.session['now'] = now
return HttpResponse('登录成功')
'''
1. 生成一个随机字符串 0ps4avkhy95v4hbh1f0bae4266zlsddd
2. response.set_cookie('sessionid',dfrtghhtyr)
3. 在django session 表中创建记录
session-key session-data
0ps4avkhy95v4hbh1f0bae4266zlsddd {'is_login':True,'username':'hhpsb'}
'''
return render(request, 'login.html')
def index_session(request):
is_login = request.session.get('is_login')
if is_login:
name = request.session.get('username')
now=request.session.get('now')
return render(request, 'index.html', locals())
return redirect('/login_session/')
login.html
<body>
<form action="" method="post">
{% csrf_token %}
用户名 <input type="text" name="user">
密码 <input type="text" name="pwd">
<input type="submit" value="submit">
</form>
</body>
index.html
<body>
<h1>hi {{ name }}</h1>
</body>
浏览访问http://127.0.0.1:8000/login_session/,验证通过后产生cookie
查看django_session表
浏览器访问http://127.0.0.1:8000/index_session/
更新session
更新操作,如果用户访问过页面,则第二次访问会带着sessionid这个cookie字段来访问,数据库表django_session中的session_key字段不变,如果添加新的session数据,数据库表中的session_data会变化
views.py
def index_session(request):
is_login = request.session.get('is_login')
if is_login:
name = request.session.get('username')
now=request.session.get('now')
request.session['xxx']='xxx' # 把这条数据加入session,session_data字段立马变化
return render(request, 'index.html', locals())
return redirect('/login_session/')
基于session的注销功能
models.py
from django.db import models
class Userinfo(models.Model):
user=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
数据库测试数据
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^login_session/', views.login_session),
url(r'^index_session/', views.index_session),
url(r'^logout/', views.logout),
]
views.py
def login_session(request):
if request.method == 'POST':
user = request.POST.get('user')
pwd = request.POST.get('pwd')
user = Userinfo.objects.filter(user=user, pwd=pwd).first()
if user:
request.session['is_login'] = True
request.session['username'] = 'hppsb'
import datetime
now = datetime.datetime.now().strftime('%Y-%m-%d %X')
request.session['now'] = now
return redirect('/index_session/')
'''
1. 生成一个随机字符串 0ps4avkhy95v4hbh1f0bae4266zlsddd
2. response.set_cookie('sessionid',dfrtghhtyr)
3. 在django session 表中创建记录
session-key session-data
0ps4avkhy95v4hbh1f0bae4266zlsddd {'is_login':True,'username':'hhpsb'}
'''
return render(request, 'login.html')
def index_session(request):
is_login = request.session.get('is_login')
if is_login:
name = request.session.get('username')
now=request.session.get('now')
return render(request, 'index.html', locals())
return redirect('/login_session/')
def logout(request):
request.session.flush()
'''
做的三步操作:
1. randon_str=request.COOKIE.get('sessionid')
2. django-session.objects.filter(session-key=randon_str).delete()
3. response.delete_cookie("sessionid",randon_str)
'''
return redirect('/login_session/')
login.html
<body>
<form action="" method="post">
{% csrf_token %}
用户名 <input type="text" name="user">
密码 <input type="text" name="pwd">
<input type="submit" value="submit">
</form>
</body>
index.html
<body>
<h1>hi {{ name }}</h1>
</body>
浏览器访问http://127.0.0.1:8000/index_session/ 按注销跳转到登录页面
session的配置参数
配置settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key, 即: sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输Cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的Cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的Cookie失效日期(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session, 默认修改后才保存(默认)