一、cookie 和 session

1.为什么会有这些技术

cookie和session的出现是为了保存客户端的用户状态。

究其本质,其实是因为HTTP协议是无状态的,没办法保存客户的登录信息及状态,因此需要用cookie和session来保存用户的状态。

cookie

cookie是客户端用来记录用户信息的一种容器,它以键值对的形式储存,比方说{'username':'st'}

当cookie发送到服务端后,服务端可以根据cookie携带的信息识别用户的身份。可以知道到底是张三在访问服务器还是李四在访问服务器。

这样就导致某些功能在被用户使用时,必须先登录,让服务端知道用户身份后才能使用。比如说淘宝的购物车,每个人都不一样,你只有登陆了,才能访问自己的购物车。

这就导致用户每次访问都要登录,显得很麻烦。如果可以登陆一次就可以记录状态,那就很方便了。

cookie应运而生。

用户登录后,登录信息保存在浏览器cookie中,只需登录一次输入信息,下一次再访问,浏览器就会自动帮你发送cookie。

服务端得知了用户信息,你也不用手动输入多次了,万事大吉,美滋滋!

session

万事无绝对。

cookie记录的用户信息往往包含了一些隐私信息。比如密码之类的敏感信息。

当cookie保存在浏览器时,cookie中的信息就会遭受各种意外泄露的风险。

一旦泄露,有可能会酿成大祸。

为了解决这个问题,session横空出世。

当用户输入信息登录时,用户信息被传入后端服务器,服务器将这些数据进行加密并保存在服务器中,然后给这份信息贴上一个名为"session_id"的标签。这个"session_id"其实只是一个随机生成的字符串,用来标记这份用户信息,方便查找的。

通过这个"session_id",服务器就可以快速的访问到这份用户信息。

这样有什么用呢?

这样浏览器就不用直接保存用户信息了。服务端可以将"session_id"返回给浏览器,浏览器将"session_id"当做cookie键值对中的值进行保存。

这样,下次用户想要进行访问时,浏览器就将包含"session_id"的cookie发给服务器,服务器通过"session_id"找到之前用户第一次登陆时保存在服务器上的信息,服务器就可以知道用户身份惹!

至此登陆成功!用户再也不用频繁输入信息,也不怕信息泄露惹!

当然,session也并不完美,但是安全性能相比于只有cookie时已经大大提高,从而被广而告之,程序员们纷纷效仿。。。

2. cookie

虽然cookie可以保存在客户端浏览器上,但是由于它是由服务端设置出来的,浏览器有权禁止cookie的写入。

2.1 Django如何设置cookie

需要用views三基类实例化出的obj对象进行cookie设置。

obj = HttpResponse()
# 利用obj对象你才可以操作cookie
# obj = render()
# obj = redirect() obj.set_cookie('k1','v1')
# 设置用盐加密的cookie
obj.set_signed_cookie(key,value,salt='加密盐',) def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'st' and password == '123':
# 如果登录信息完整,就返回主页
obj = redirect('/home/') # 告诉浏览器,保存这一对cookie
obj.set_cookie('username','st') return obj
return render(request,'login.html')

2.2 Django如何获取cookie

def home(request):
if request.COOKIES.get('username'):
print(request.COOKIES.get('username'))
# st
return HttpResponse('只有登录的人才能看到')
return redirect('/login/')

2.3 Django如何设置cookie的超时时间

set_cookies使用max_age、expires参数

obj.set_cookie('k1','v1',max_age=3)
obj.set_cookie('k1','v1',expires=3)
# 两个参数都是设置超时时间 并且都是以秒为单位
# 区别:expires可以给IE浏览器设置cookie的超时时间 def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'st' and password == '123':
obj = redirect('/home/')
obj.set_cookie('username','st',expires=3)
# 告诉浏览器,保存这一对cookie
# expires=3单位为秒,max_age一样
return obj
return render(request,'login.html')

2.4 Django如何通过cookie跳转到想要访问的页面

可以在登录认证装饰器中完成

# 用来跳回用户登录前想访问的页面的装饰器
from functools import wraps
def login_auth(func):
@wraps(func) # 函数用wraps,类用update_wrapper
def inner(*args,**kwargs):
# 判断当前用户是否登录
request = args[0]
# print(request)
# print(request.GET)
# print(request.path_info) # 只获取url,不获取get参数
# print(request.get_full_path()) # # url+get参数
if request.COOKIES.get('username'):
res = func(*args, **kwargs)
return res
else:
# 获取到用户想要访问的页面的url
path = request.path_info
# 将该url当做get参数传入login函数
return redirect(f'/login/?path={path}')
return inner # login
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'st' and password == '123':
# 获取get参数,取得用户想要访问的url
path = request.GET.get('path')
if path:
obj = redirect(path)
else:
# 如果path没值,可能用户是直接访问的login视图,因此登录后默认返回到home首页
obj = redirect('/home/') obj.set_cookie('username','st')
return obj
return render(request,'login.html')

2.5 Django如何删除cookie

delete_cookie函数删除cookie。

def logout(request):
obj = redirect('/logout/')
obj.delete_cookie('username')
return obj

3. session

session是保存在服务端上的键值对。

session的工作机制是需要依赖于cookie的。

3.1 Django设置session

默认失效时间为两周,14天

def set_session(request):
request.session['k1'] = 'ok123'
return HttpResponse('session已设置')

Django内部到底发生了什么:

  1. 将获取到的数据以键值对的形式添加到一个大字典中,将这个字典加密保存。
  2. 自动生成一个随机的字符串,作为上一步获取的加密数据的session_id。以键值对{'session_id':加密数据}的形式保存在储存器中。可以通过session_id来获取对应的加密数据。
  3. 将session_id返回给前端浏览器。这样下次浏览器访问时携带cookie,服务器后端可以获取cookie中的session_id,这样就可以通过session_id获取储存器中储存的加密数据。然后通过‘加密数据加密时使用的加密算法’所对应的解密算法将加密数据解密,就可以获取以键值对形式储存的数据了。
  4. 当下一次同一个浏览器需要在储存一组隐私数据时,django自动解密出该浏览器所对应的大字典,将新加入的键值对添加到这个大字典中,重新加密,保存,替代之前的加密大字典,这样,一个浏览器就会只有一条数据了。

3.2 Django获取session

# 获取session
def get_session(request):
res = request.session.get('k1')
print(res)
return HttpResponse('获取成功')

Django内部到底发生了什么:

  1. Django服务端从前端浏览器处获取到cookie
  2. 从cookie中取出相应的'session_id'值
  3. 在数据库中通过session_id获取对应的大字典加密值
  4. 将加密大字典解密,获取大字典
  5. request.session=大字典
  6. 然后request.session就可以通过'.get'的方式从字典中取值了。
res = dict(request.session)
print(res) # 强制类型转换一下,发现确实是一个字典
# {'k1': 'ok123', 'k2': 'ok321'}

3.3 Django删除session

# 删除session
def del_session(request): # 删除当前会话的所有Session数据
# request.session.delete() # 删除当前的会话数据并删除会话的Cookie,
# 用于确保前面的会话数据不可以再次被用户的浏览器访问.建议使用
request.session.flush()
return HttpResponse('shanle ')

3.4 Django设置session失效时间

# request.session.set_expiry(value)
request.session.set_expiry(5) # 单位为秒

当某条session失效后,这个数据就会从有效的大字典中被筛选出,单独放在session表里作为一条数据,它不会立马被清除,而是先存在session表里,每过一段时间,django就会启用自动清除功能,将失效时间已过的session删除。

3.5 Django设置储存session的存储器

1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其他公用设置项:
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失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) Django中Session相关设置

二、Django中间件

1. 默认中间件

如果你想要做一些网站的全局性功能,你都应该优先考虑使用django的中间件。

例如:

1.全局的用户登录校验

2.全局的用户访问频率校验

3.全局的用户权限校验()

django的中间件是所有框架里面做的最完善的。

# settings
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

以上就是django默认的七种中间件。

中间件的本质其实就是一个个的类,类中的以下方法会在特定的阶段自动触发:

1.process_request

2.process_response

3.process_view

4.process_template_response

5.process_exception

2. 自定义中间件

自定义中间件需要自己创建一个py文件,名字可以随便取,然后在这个文件中导入MiddlewareMixin模块产生子类。

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,render,redirect
# 接下来可以定义类,继承MiddlewareMixin模块,该类就成为了一个中间件 class MyMdd1(MiddlewareMixin):
def process_request(self,request):
pass # 。。。。。。

2.1. 需要掌握

  1. process_request

    1.请求来的时候会按照settings配置文件中从上往下的顺序,依次执行每一个中间件内部定义的process_request方法。

    2.如果中间件内部没有该方法,直接跳过执行下一个中间件。

    3.该方法一旦返回了HttpResponse对象,那么请求会立刻停止往回走,立即原路返回。

    4.当process_request方法直接返回HttpResponse对象之后 会直接从当前中间件里面的process_respone往回走。原路返回。没有执行的中间件都不会再执行。

def process_request(self,request):
print('我是第一个中间件里面的process_request方法')
# return HttpResponse("我是中间件一里面的")
  1. process_response

    1.响应走的时候会按照settings配置文件中从下往上的顺序,依次执行每一个中间件内部定义的process_response方法。

    2.该方法必须有两个形参,并且必须返回response形参,不返回直接报错。

    3.该方法返回什么(HttpResponsed对象)前端就能获得什么。

def process_response(self,request,response):
"""
:param request:
:param response: 就是后端返回给前端的数据
:return:
"""
print('我是第一个中间件里面的process_response方法')
return response

2.2 了解

  1. process_view

    1.路由匹配成功之后执行视图函数之前触发。

    2.如果该方法返回了HttpResponse对象,那么会从下往上一次经过每一个中间件里面的process_response方法。

def process_view(self,request,view_name,*args,**kwargs):
print(view_name) # 函数内存地址
print(args)
print(kwargs)
print('我是第一个中间件里面的process_view方法')
  1. process_template_response

    1.在视图函数执行完成后立即执行,但有一个前提条件,那就是视图函数返回的对象必须有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。不然不会触发。

def process_template_response(self, request, response):
print('我是第一个中间件里面的奇葩方法')
return response # views
def mdzz(request):
print('我是视图函数mdzz')
def render():
return HttpResponse('你好呀 我是奇葩')
obj = HttpResponse('我很好 好的像个傻逼一样')
obj.render = render
return obj
  1. process_exception

    1.当视图函数中出现错误时会自动触发,顺序是从下往上

def process_exception(self,request,exception):
print('我是第一个中间件里面的process_exception')
print(exception)

Django框架-cookie和session以及中间件的更多相关文章

  1. Django之cookie与session、中间件

    目录 cookie与session 为什么会有cookie和session cookie 设置cookie 获取cookie 删除cookie 实例:cookie版登录校验 session 设置ses ...

  2. day13 cookie与session和中间件

    day13 cookie与session和中间件 今日内容概要 cookie与session简介 django操作cookie与session django中间件简介 如何自定义中间件 csrf跨站请 ...

  3. Django之Cookie、Session、CSRF、Admin

    Django之Cookie.Session.CSRF.Admin   Cookie 1.获取Cookie: 1 2 3 4 5 6 request.COOKIES['key'] request.get ...

  4. [py][mx]django的cookie和session操作-7天免登录

    浏览器同源策略(same-origin policy) csrf攻击防御核心点总结 django的cookie和session操作-7天免登录 flask操作cookie&django的see ...

  5. Django基础cookie和session

    Django基础cookie和session 1.会话跟踪 ​ 什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如给10086打个电话,你就是客户端, ...

  6. Django --- cookie与session,中间件

    目录 1.cookie与session 1.cookie 2.session 2.中间件 1.中间件作用 2.用户可以自定义的五个方法 3.自定义中间件 1.cookie与session 1.cook ...

  7. web框架开发-Django组件cookie与session

    http协议的每一次都是无保存状态的请求,这会带来很多的不方便,比如,一刷新网页,或者进入该网页的其他页面,无法保存之前的登录状态.为了解决类似这样的问题,引入了会话跟踪 会话跟踪技术 1 什么是会话 ...

  8. pyhton框架Django之cookie和session

    一,cookie和session的理解 cookies 是浏览器为 Web 服务器存储的一小段信息. 每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的cookies.它保存在浏览器下的某个文 ...

  9. django框架--cookie/session

    目录 一.http协议无状态问题 二.会话跟踪技术--cookie 1.对cookie的理解 2.cookie的使用接口 3.cookie的属性 4.使用cookie的问题 三.会话跟踪技术--ses ...

随机推荐

  1. hdu1394Minimum Inversion Number

    Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...

  2. Codeforces Round #696 (Div. 2) C. Array Destruction (贪心,multiset)

    题意:有\(n\)个数,首先任选一个正整数\(x\),然后在数组中找到两个和为\(x\)的数,然后去掉这两个数,\(x\)更新为两个数中较大的那个.问你最后时候能把所有数都去掉,如果能,输出最初的\( ...

  3. tomacat配置虚拟主机 && 配置缺省页面

    在conf文件夹下的server.xml文件中 在c盘建立一个sina文件夹,里面建立一个mail文件夹,在mail文件夹下面建立一个1.html网页 你配置完如果直接访问http://www.sin ...

  4. JavaScript——五

    onload:在加载的时候 因为网页代码是从上到下执行的,所以我们有些对网页内容的操作要先加载出网页内容后再执行script的内容,这个时候如果没有onload我们只能写在这些内容的后面,但是有了lo ...

  5. PowerShell随笔2---初始命令

    PowerShell便捷之处 PowerShell中兼容运行cmd的命令,比如 ipconfig.ping命令等 PowerShell的命令更友好,可读性更强.比如停止一个服务 CMD命令:sc st ...

  6. python3 anaconda 安装pyhook3 pythoncom(pywin32)

    为什么不安装pyhook 1.pyhook不支持python3 2.网络上有一些方法下载pyhook的whl然后pip安装到python3,可以运行,但是会因为编码问题导致移动到窗口标题含有非ASCI ...

  7. 利用设置新数据存储结构解决vue中折叠面板双向绑定index引起的问题

    问题背景是,在进行机器性能可视化的前端开发时,使用折叠面板将不同机器的性能图表画到不同的折叠面板上去.而机器的选择利用select下拉选项来筛选. 由于在折叠面板中,通过 如下v-model双向绑定了 ...

  8. Linux 驱动框架---模块参数

    Linux 模块的参数 通过在内核模块中定义模块参数从而可以在安装模块时通过insmod module_name paramname=param形式给模块传递参数.如果安装模块是传参数则将使用模块内定 ...

  9. Linux 驱动框架---cdev字符设备驱动和misc杂项设备驱动

    字符设备 Linux中设备常见分类是字符设备,块设备.网络设备,其中字符设备也是Linux驱动中最常用的设备类型.因此开发Linux设备驱动肯定是要先学习一下字符设备的抽象的.在内核中使用struct ...

  10. 使用 js 实现一个简易版的 GIPHY 动图搜索 web 应用程序

    使用 js 实现一个简易版的 GIPHY 动图搜索 web 应用程序 具有挑战性的前端面试题 API JAMstack refs https://www.infoq.cn/article/0NUjpx ...