Python Web框架之Django框架cookie和session用法分析


Posted in Python onAugust 16, 2019

本文实例讲述了Python Web框架之Django框架cookie和session用法。分享给大家供大家参考,具体如下:

part 1 概念

在Django里面,cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话。

两者最大的区别是cookie的信息是存放在浏览器客户端的,而session是存放在服务器端的。

两者使用的方式都是request.COOKIES[XXX]request.session[XXX],其中XXX是您想要取得的东西的key。

Cookie——保存在客户端浏览器上的键值对

只要是HTTP协议,就会有COOKIE这个东西; 只要您的浏览器没有禁用Cookie,就可是使用它。而且是不分用什么语言,用什么框架,因为这是在HTTP协议的层面支持的,浏览器会把您设置的XXX的这个Cookie在Response之后保存到您的本地机器,在下次您向服务器提交或者浏览的时候会把上次保存下来的COOKIE带上发送向服务器;说到这里我们应该澄清一个概念,就是BS结构理论上是没有同步的服务器-客户端的状态维持的,所以Cookie本质上就是一种异步的状态维护,所有这一切浏览器都帮我们搞定了,所以不用关心。 当然如果使用是Django的话,最终的HttpRequest也许是WSGIRequest(调试的时候使用WSGI方式),也许是ModPythonRequest(使用Apache+Mod_python的方式),他们都是一个HTTP协议要求的Requset的实现;

Session是保存在服务器端的键值对,session内部机制依赖于cookie

我们都知道Django可以通过meddleware来修改requset和response,如果想使用Django当中Session,

首先必须要求您的Django工程的settiongs.py文件里面的MIDDLEWARE_CLASSES设置里面已经包含有django.contrib.sessions.middleware.SessionMiddleware(其实默认就是有的)。

接下来我们看看/django/contrib/sessions/middleware.py这个文件,里面定义了一个SessionMiddleware的class,

其中的process_request函数有一句话:

session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)

我们所使用的request.session当中的sesson这个变量就是在这一刻诞生的

这个类是根据得到COOKIES里面的settings.SESSION_COOKIE_NAME来生成

如果浏览器不支持Cookie的话,Django的Session也就无从用起了,因为Session的生成是根据Cookie里面记录的SESSION_COOKIE_NAME来生成的

part 2  cookie

1,views视图函数

user_info = {
  'user1': {'pwd': "123123"},
  'user2': {'pwd': "kkkkkkk"},
}
def login(request):
  if request.method == "GET":
    return render(request,'login.html')
  if request.method == "POST":
    u = request.POST.get('username')
    p = request.POST.get('pwd')
    dic = user_info.get(u)
    if not dic:
      return render(request,'login.html')
    if dic['pwd'] == p:
      res = redirect('/index/')
      # res.set_cookie('user1',u,max_age=10)
      # import datetime
      # current_date = datetime.datetime.utcnow()
      # current_date = current_date + datetime.timedelta(seconds=5)
      # res.set_cookie('user1',u,expires=current_date)
      res.set_cookie('user1',u)
      res.set_cookie('user_type',"asdfjalskdjf",httponly=True)
      return res
    else:
      return render(request,'login.html')
def auth(func):
  def inner(reqeust,*args,**kwargs):
    v = reqeust.COOKIES.get('user1')
    if not v:
      return redirect('/login/')
    return func(reqeust, *args,**kwargs)
  return inner
@auth
def index(reqeust):
  # 获取当前已经登录的用户
  v = reqeust.COOKIES.get('user1')
  return render(reqeust,'index.html',{'current_user': v})
from django import views
from django.utils.decorators import method_decorator
@method_decorator(auth,name='dispatch')
class Order(views.View):
  # @method_decorator(auth)
  # def dispatch(self, request, *args, **kwargs):
  #   return super(Order,self).dispatch(request, *args, **kwargs)
  # @method_decorator(auth)
  def get(self,reqeust):
    v = reqeust.COOKIES.get('user1')
    return render(reqeust,'index.html',{'current_user': v})
  def post(self,reqeust):
    v = reqeust.COOKIES.get('user1')
    return render(reqeust,'index.html',{'current_user': v})
def order(reqeust):
  # 获取当前已经登录的用户
  v = reqeust.COOKIES.get('user1')
  return render(reqeust,'index.html',{'current_user': v})
def cookie(request):
  # request.COOKIES
  # request.COOKIES['user1']
  request.COOKIES.get('user1')
  response = render(request,'index.html')
  response = redirect('/index/')
  # 设置cookie,关闭浏览器失效
  response.set_cookie('key',"value")
  # 设置cookie, N秒只有失效
  response.set_cookie('user1',"value",max_age=10)
  # 设置cookie, 截止时间失效
  import datetime
  current_date = datetime.datetime.utcnow()
  current_date = current_date + datetime.timedelta(seconds=5)
  response.set_cookie('user1',"value",expires=current_date)
  response.set_cookie('user1',"value",max_age=10)
  # request.COOKIES.get('...')
  # response.set_cookie(...)
  obj = HttpResponse('s')
  obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf")
  request.get_signed_cookie('username',salt="asdfasdf")
  return response

代码详解:

1.1 login函数渲染登录页面,同时设置cookie

1.2 装饰器

FBV(function base views) 就是在视图里使用函数处理请求。

auth装饰器相当于下面的index函数

def index(reqeust):
  # 获取当前已经登录的用户
  v = reqeust.COOKIES.get('user1')
  if not v:
    return redirect('/login/')
  return render(reqeust,'index.html',{'current_user': v})

CBV(class base views) 就是在视图里使用类处理请求。

@method_decorator(auth,name='dispatch')#写在这里表示对dispatch装饰
class Order(views.View):
  # @method_decorator(auth) #写在这里,规则要通过dispatch,dispatch不符合就下面也用不上
  #dispath方法在执行下面方法之前执行
  def dispatch(self, request, *args, **kwargs):
    return super(Order,self).dispatch(request, *args, **kwargs)
  # @method_decorator(auth)写在这里只能对get做验证,对post无用
  def get(self,reqeust):
    v = reqeust.COOKIES.get('user1')
    return render(reqeust,'index.html',{'current_user': v})

1.4 cookie增删改查操作:

1、设置Cookies

response.set_cookie("cookie_key","value")

2、获取Cookies

value = request.COOKIES["cookie_key"]
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

参数:

  • default: 默认值
  • salt: 加密盐
  • max_age: 后台控制过期时间

3、删除Cookies

response.delete_cookie("cookie_key",path="/",domain=name)

4、检测Cookies

if "cookie_name" is request.COOKIES :

5、设置加密的cookie

rep.set_signed_cookie(key,value,salt='加密盐',...)

参数:

  •         key,              键
  •         value='',         值
  •         max_age=None,     超时时间,表示多少秒数之后失效
  •         expires=None,     超时时间,表示失效的时间点。支持datetime 和 time.time
  •         path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
  •         domain=None,      Cookie生效的域名
  •         secure=False,     https传输
  •         httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

2,index页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <h1>欢迎登录:{{ current_user }}</h1>
</body>
</html>

3,login页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <form action="/login/" method="POST">
    <input type="text" name="username" placeholder="用户名" />
    <input type="password" name="pwd" placeholder="密码" />
    <input type="submit" />
  </form>
</body>
</html>

运行django之后,访问index,会自动跳转到login页面,输入账户密码之后,自动跳转到index,并从cookie中取出username,打印出来

part 3  session

正常情况下,你无需任何设置就可以使用session功能。如果你删除或修改过请检测一下配置

1、编辑settings.py中MIDDLEWARE_CLASSES 配置,确保 'django.contrib.sessions.middleware.SessionMiddleware'存在,如果没有则添加。

2、编辑settings.py中INSTALLED_APPS配置,确保'django.contrib.sessions' (如果你是刚打开这个应用,别忘了运行 manage.py syncdb )

Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:

只需要更改settings/py文件中的SESSION_ENGINE

数据库配置settings.py(默认):

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

1.配置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失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False              # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False                   # 是否每次请求都保存Session,默认修改之后才保存(默认)

缓存配置settings.py:

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
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,默认修改之后才保存

文件配置settings.py:

SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH = None   # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
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,默认修改之后才保存

缓存+数据库配置settings.py:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

加密cookie配置settings.py:

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'

sessions使用:

1.获取、设置、删除Session中数据

def index(request):
request.session['k1']                  #获取session,如果没有会报错
request.session.get('k1',None)       #获取session,如果没有会返回None
request.session['k1'] = 123             #设置session,如果k1存在就覆盖
request.session.setdefault('k1',123) #设置session,如果存在则不设置
del request.session["k1"]              #只删除k1,随机字符串和其他session值还存在
request.session.session_key             #当前用户随机字符串

2.所有 键、值、键值对

request.session.keys()         #获取所有键
request.session.values()     #获取所有值
request.session.items()        #获取所有的键值
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()

request.session.session_key # 用户session的随机字符串

request.session.clear_expired() #将所有Session失效日期小于当前日期的数据删除

request.session.exists("session_key") # 检查 用户session的随机字符串 在数据库中是否

request.session.delete("session_key") # 删除当前用户的所有Session数据

request.session.set_expiry(value)

  •         * 如果value是个整数,session会在些秒数后失效。
  •         * 如果value是个datatime或timedelta,session就会在这个时间后失效。
  •         * 如果value是0,用户关闭浏览器session就会失效。
  •         * 如果value是None,session会依赖全局session失效策略。

希望本文所述对大家基于Django框架的Python程序设计有所帮助。

Python 相关文章推荐
python高并发异步服务器核心库forkcore使用方法
Nov 26 Python
Python中常见的数据类型小结
Aug 29 Python
Python实现二叉树结构与进行二叉树遍历的方法详解
May 24 Python
Python中利用xpath解析HTML的方法
May 14 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
Oct 23 Python
pygame游戏之旅 调用按钮实现游戏开始功能
Nov 21 Python
Python3 导入上级目录中的模块实例
Feb 16 Python
python3 线性回归验证方法
Jul 09 Python
Window10下python3.7 安装与卸载教程图解
Sep 30 Python
python中seaborn包常用图形使用详解
Nov 25 Python
Python3与fastdfs分布式文件系统如何实现交互
Jun 23 Python
Python .py生成.pyd文件并打包.exe 的注意事项说明
Mar 04 Python
python中hasattr()、getattr()、setattr()函数的使用
Aug 16 #Python
Python中IP地址处理IPy模块的方法
Aug 16 #Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
Aug 16 #Python
Pyinstaller 打包exe教程及问题解决
Aug 16 #Python
python函数参数(必须参数、可变参数、关键字参数)
Aug 16 #Python
Python Web框架之Django框架文件上传功能详解
Aug 16 #Python
基于 Django 的手机管理系统实现过程详解
Aug 16 #Python
You might like
php目录管理函数小结
2008/09/10 PHP
如何使用php判断所处服务器操作系统的类型
2013/06/20 PHP
解决php使用异步调用获取数据时出现(错误c00ce56e导致此项操作无法完成)
2013/07/03 PHP
phpcms实现验证码替换及phpcms实现全站搜索功能教程详解
2017/12/13 PHP
JQuery学习笔记 nt-child的使用
2011/01/17 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
2014/03/05 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
2014/04/08 Javascript
js图片预加载示例
2014/04/30 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
jQuery根据name属性进行查找的用法分析
2016/06/23 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
vue.js实现刷新当前页面的方法教程
2017/07/05 Javascript
js封装成插件_Canvas统计图插件编写实例
2017/09/12 Javascript
web前端页面生成exe可执行文件的方法
2018/02/08 Javascript
JavaScript设计模式之模板方法模式原理与用法示例
2018/08/07 Javascript
详解webpack-dev-server使用方法
2018/09/14 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
2018/12/24 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
bootstrap-paginator服务器端分页使用方法详解
2020/02/13 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
[09:13]2014DOTA2国际邀请赛 中国区预选赛coser表演
2014/05/23 DOTA
Python设计模式之观察者模式原理与用法详解
2019/01/16 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
Django Channels 实现点对点实时聊天和消息推送功能
2019/07/17 Python
Python Pandas 如何shuffle(打乱)数据
2019/07/30 Python
爬虫代理的cookie如何生成运行
2020/09/22 Python
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
M.M.LaFleur官网:美国职业女装品牌
2020/10/27 全球购物
委托与事件是什么关系?为什么要使用委托
2014/04/18 面试题
会议接待欢迎标语
2014/10/08 职场文书
医德医风个人工作总结2014
2014/11/14 职场文书
幼儿园体操比赛口号
2015/12/25 职场文书
如何用JS实现网页瀑布流布局
2021/04/24 Javascript
Python实现机器学习算法的分类
2021/06/03 Python