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正则表达式 re模块使用说明
May 19 Python
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 Python
python实现删除文件与目录的方法
Nov 10 Python
Python实现快速排序算法及去重的快速排序的简单示例
Jun 26 Python
python数据预处理之将类别数据转换为数值的方法
Jul 05 Python
python TKinter获取文本框内容的方法
Oct 11 Python
python多进程使用及线程池的使用方法代码详解
Oct 24 Python
Python3中exp()函数用法分析
Feb 19 Python
python打印直角三角形与等腰三角形实例代码
Oct 20 Python
python绘制无向图度分布曲线示例
Nov 22 Python
解决pycharm中的run和debug失效无法点击运行
Jun 09 Python
Python如何自动获取目标网站最新通知
Jun 18 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
全文搜索和替换
2006/10/09 PHP
Yii的CDbCriteria查询条件用法实例
2014/12/04 PHP
php中smarty模板条件判断用法实例
2015/06/11 PHP
PHP生成plist数据的方法
2015/06/16 PHP
详解PHP的Yii框架中组件行为的属性注入和方法注入
2016/03/18 PHP
smarty的section嵌套循环用法示例
2016/05/28 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
javascript面向对象之二 命名空间
2011/02/08 Javascript
js中top/parent/frame概述及案例应用
2013/02/06 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
jQuery中insertBefore()方法用法实例
2015/01/08 Javascript
jQuery仿Flash上下翻动的中英文导航菜单实例
2015/03/10 Javascript
浅析jQuery事件之on()方法绑定多个选择器,多个事件
2016/04/27 Javascript
微信小程序 本地数据读取实例
2017/04/27 Javascript
jquery实现选项卡切换代码实例
2019/05/14 jQuery
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
[02:33]2018DOTA2亚洲邀请赛赛前采访——LGD
2018/04/04 DOTA
python小技巧之批量抓取美女图片
2014/06/06 Python
Python实现对字符串的加密解密方法示例
2017/04/29 Python
python+POP3实现批量下载邮件附件
2018/06/19 Python
Django外键(ForeignKey)操作以及related_name的作用详解
2019/07/29 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
css3利用transform变形结合事件完成扇形导航
2020/10/26 HTML / CSS
REISS美国官网:伦敦最受欢迎的时尚品牌
2019/08/16 全球购物
写出二分查找算法的两种实现
2013/05/13 面试题
介绍一下SQL中union,intersect和minus
2012/04/05 面试题
介绍一下EJB的体系结构
2012/08/01 面试题
几道Web/Ajax的面试题
2016/11/05 面试题
心理学专业毕业生推荐信范文
2013/11/21 职场文书
教师求职信范文分享
2013/12/27 职场文书
四年大学生活的自我评价范文
2014/02/07 职场文书
支部鉴定材料
2014/06/02 职场文书
五月的鲜花活动方案
2014/08/21 职场文书
会计试用期工作总结2015
2015/05/28 职场文书
CocosCreator ScrollView优化系列之分帧加载
2021/04/14 Python
分析Python list操作为什么会错误
2021/11/17 Python