阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

会话控制

187次阅读
没有评论

共计 5283 个字符,预计需要花费 14 分钟才能阅读完成。

一、会话控制 COOKIE

1、概述

会话控制 用来保持用户的状态 具体来说 cookie 机制采用的是在客户端保持状态的方案,而 session 机制采用的是在服务器端保持状态的方案

2、原因

http 协议时无状态的

每一次请求都是一次新的请求,不会记得之前的通信状态

3、值的存储

cookie 存储在客户端的浏览器 一般会限制存储 cookie 的个数为 20 个 并且单个 cookie 保存值的大小不能超过 4kb 存储在浏览器上为明文存储 所以不安全

4、设置 cookie

  • 方法

    set_cookie()

  • 原型

    set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False)
  • 参数

    • key cookie 的键
    • value cookie 的值
    • max_age 最长使用时间(秒为单位)
    • expires 过期时间,优先级高(秒为单位)
    • path 生效的路径
    • domain 生效的域名
    • secure HTTPS 传输时应设置为 true
    • httponly 仅 http 传输 不能使用 js 获取 cookie
  • 示例

    设置 cookie 不设置过期时间

    path('setcookie/',views.set_cookie_view),
    def set_cookie_view(req): res = HttpResponse('设置 cooke') res.set_cookie('name','lucky') return res

    注意:如果没有设置 Cookie 超时时间,表示关闭浏览器之后自动删除 Cookie,Cookie 尽量避免存储敏感信息

    设置 cookie 并设置过期时间

    url(r'^set_cookie_lifetime/',views.set_cookie_lifetime),
    def set_cookie_lifetime(req): res = HttpResponse('设置 cooke 并设置过期时间') # 设置过期时间为一分钟 # res.set_cookie('name','lucky',max_age=60) res.set_cookie('name','zhangsan',expires=60) return res

5、获取 cookie

  • 属性

    request.COOKIES

  • 格式

    request.COOKIES.get(key)

  • 示例

    path('^get_cookie/',views.get_cookie),
    # 获取 cookie def get_cookie(req): print(req.COOKIES) value = req.COOKIES.get('name') return HttpResponse("值为{}".format(value))

6、删除 cookie

  • 方法

    delete_cookie()

  • 格式

    res.delete_cookie(key)

  • 示例

    path('^delete_cookie/',views.delete_cookie_view),
    def delete_cookie_view(req): res = HttpResponse('删除 cookie') res.delete_cookie('name') return res

二、会话控制 SESSION

1、概述

  • 说明

    服务器需要识别来自同一访问者的请求,这主要是通过浏览的 cookie 实现的。访问者在第一次访问服务器时,服务器在其 cookie 中设置一个唯一的 ID 号——会话 ID。这样,访问者后续对服务器的访问头中将自动包含该信息,服务器通过这个 ID 号,即可区 隔不同的访问者

  • 会话

    客户端与服务端一次通信称之为一次会话

  • http 协议时无状态的

    每一次请求都是一次新的请求,不会记得之前的通信状态

  • 状态保持

    将会话信息得到存储

  • 存储的位置

    存储在服务端:session

  • Session 存储结构

    以键值对方式存储

2、启用 session

  • settings.py 文件

    INSTALLED_APPS = ['django.contrib.sessions', ] MIDDLEWARE = ['django.contrib.sessions.middleware.SessionMiddleware', ]
  • 注意

    启用 session 后 request 对象才会有 session 属性

3、使用 session

  • 生成 session 存储所需要的系统表

    python manage.py migrate

  • 设置 session 不设置过期时间

    • 格式

      request.session[key] = value

    def set_session(req): req.session['name'] = 'lucky' req.session['sex'] = 'man' return HttpResponse('设置 session')

    注意:session 默认存活时间为 俩周

    可以去库中查看 django_session 表 把 session 的值使用 base64 解码出来

  • 设置 session 并设置过期时间

    • 格式

      request.session.set_expiry(value)

      value 值:

      • integer 整数 秒
      • 0 当前浏览会话结束
      • datetime
      • timedelta
      • None 依赖于全局 session 过期
    def set_session_lifetime(req): req.session.set_expiry(60) # 过期时间 1 分钟 req.session['name'] = 'lucky' return HttpResponse('设置 session 并设置过期时间')
  • 获取 session

    def get_session(req): v = req.session.get('name','default') return HttpResponse('获取 session-----{}'.format(v))
  • 删除 session

    • clear() 清空所有 session 会将 session 存储数据删除 但是不会将表中的整条 session 数据清除
    • flush() 清空所有 并删除表中的 session 数据
    • logout(request) 清空所有 并删除表中的 session 数据
    • del request.session[key] 删除某个 session 的值
    from django.contrib.auth import logout def del_session(req): req.session.flush() # 清除所有 session req.session.clear() # 清除所有 session 不删除表中数据 logout(req) # 清除所有 session del req.session['name'] # 删除 key 为 name 的 session return HttpResponse('清除 session')

4、存储原理

会话控制

5、存储位置

  • 基于数据库的会话

    默认的会话存储方式

    SESSION_ENGINE = "django.contrib.sessions.backends.db"
  • 基于缓存的会话

    只存在本地内存中,如果丢失则不用找回,但是比数据库的方式读写更快

    SESSION_ENGINE = "django.contrib.sessions.backends.cache"
  • 基于缓存和数据库的会话

    优先从本地缓存中获取,如果没有则从数据库中获取再同步到缓存

    SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
  • redis 作为缓存使用

    安装

    • sudo pip install redis
    • sudo pip install django-redis-sessions==0.5.6

    配置

    SESSION_ENGINE = "redis_sessions.session" SESSION_REDIS_HOST = "10.0.12.34" # 主机 SESSION_REDIS_POST = 6379 # 端口 SESSION_REDIS_DB = 0 # 选择数据库 SESSION_REDIS_PASSWORD = "lucky" # 密码 SESSION_REDIS_PREFIX = "session" # 前缀

6、cookie 和 session 的区别

  • cookie 数据存放在客户的浏览器上,session 数据放在服务器上。

  • cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗,考虑到安全应当使用 session

  • session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能

    考虑到减轻服务器性能方面,应当使用 COOKIE

  • 单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie

  • 所以个人建议

    将登陆信息等重要信息存放为 SESSION
    其他信息如果需要保留,可以放在 COOKIE 中

7、状态保持示例代码

  • 路由

    path('index/', views.index), path('login/', views.login), path('dologin/', views.dologin), path('logout/', views.logout),
  • 视图

    from django.shortcuts import render,HttpResponse,redirect,reverse # 首页 def index(req): return render(req, 'index.html') # 登录 def login(req): return render(req,'login.html') # 登录处理 def dologin(req): username = req.POST.get('username') userpass = req.POST.get('userpass') if username=='lucky' and userpass=='lucky123456': req.session['uid'] = 1 req.session['username'] = username return redirect(reverse('App:index')) return redirect(reverse('App:login')) # 退出登录 def logout(req): req.session.flush() return HttpResponse("<meta http-equiv='refresh'content='4;/'> 退出成功 4 秒后条到首页 如不能跳到首页 请手动点击 <a href='https://www.zutuanxue.com/'> 首页 </a>")
  • 模板

    index.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <style> nav{width: 100%; height: 40px; background-color: #000; line-height: 40px; } nav span{float: right; color: #fff; margin-right: 20px; } nav>span>a{color:#fff; font-size: 16px; text-decoration: none; } </style> </head> <body> <nav> {% if username %} <nav><span>欢迎:{{username}} | <a href="{% url'App:logout'%}">退出登录</a></span></nav> {% else %} <span><a href="{% url'App:login'%}">登录 </a> | <a href="#"> 注册</a></span></nav> {% endif %} <h1>首页</h1>

    login.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <marquee behavior="" direction=""><h2>登录</h2></marquee> <center> <form action="{% url'App:dologin'%}" method="POST"> <p>用户名: <input type="text" name="username" minlength="6" maxlength="10" placeholder="请输入用户名..."></p> <p>密码: <input type="text" name="userpass" onkeyup="(this.v=function(){this.value=this.value.replace(/[^0-9-]+/,'');}).call(this)" onblur="this.v();" placeholder=" 请输入密码..." maxlength="10"></p> <p><input type="submit" value="submit"></p> </form> </center> </body> </html>

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-05-26发表,共计5283字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中