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爬虫 正则表达式使用技巧及爬取个人博客的实例讲解
Oct 20 Python
使用Python写一个小游戏
Apr 02 Python
Python3.6通过自带的urllib通过get或post方法请求url的实例
May 10 Python
Python简单获取网卡名称及其IP地址的方法【基于psutil模块】
May 24 Python
python3.7 的新特性详解
Jul 25 Python
Python 中判断列表是否为空的方法
Nov 24 Python
python实现处理mysql结果输出方式
Apr 09 Python
Python数据可视化图实现过程详解
Jun 12 Python
Python 为什么推荐蛇形命名法原因浅析
Jun 18 Python
Python 通过正则表达式快速获取电影的下载地址
Aug 17 Python
python如何实时获取tcpdump输出
Sep 16 Python
python实现黄金分割法的示例代码
Apr 28 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入库和出库
2013/06/25 PHP
php发送post请求的三种方法
2014/02/11 PHP
PHP实例分享判断客户端是否使用代理服务器及其匿名级别
2014/06/04 PHP
Yii2创建表单(ActiveForm)方法详解
2016/07/23 PHP
swoole锁的机制代码实例讲解
2021/03/04 PHP
28个JS验证函数收集
2010/03/02 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
jQuery 开发者应该注意的9个错误
2012/05/03 Javascript
JavaScript生成GUID的多种算法小结
2013/08/18 Javascript
JavaScript通过Date-Mask将日期转换成字符串的方法
2015/06/04 Javascript
JS基于构造函数实现的菜单滑动显隐效果【测试可用】
2016/06/21 Javascript
jQuery获取同级元素的简单代码
2016/07/09 Javascript
JS 全屏和退出全屏详解及实例代码
2016/11/07 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
2017/01/05 Javascript
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
2017/03/21 jQuery
vue组件间通信子与父详解(二)
2017/11/07 Javascript
微信小程序实现自定义modal弹窗封装的方法
2018/06/15 Javascript
Nodejs中的JWT和Session的使用
2018/08/21 NodeJs
vue-cli webpack配置文件分析
2019/05/20 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
Vue中常用rules校验规则(实例代码)
2019/11/14 Javascript
[44:01]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS paiN
2018/03/31 DOTA
[36:54]Mineski vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python 算法 排序实现快速排序
2012/06/05 Python
python机器学习理论与实战(二)决策树
2018/01/19 Python
python抓取网页中链接的静态图片
2018/01/29 Python
Python对List中的元素排序的方法
2018/04/01 Python
python 集合 并集、交集 Series list set 转换的实例
2018/05/29 Python
HTML5+CSS设置浮动却没有动反而在中间且错行的问题
2020/05/26 HTML / CSS
远程Wi-Fi宠物监控相机:Petcube
2017/04/26 全球购物
Senreve官网:美国旧金山的奢侈手袋品牌
2019/03/21 全球购物
介绍一下Linux中的链接
2016/05/28 面试题
邮政员工辞职信
2014/01/16 职场文书
幼儿园健康教育方案
2014/06/14 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
vue特效之翻牌动画
2022/04/20 Vue.js