八、django的cookie和session

简介

早起的web应用都相对简单,只是简单的展示内容,无需记录用户的状态信息(例如登录状态等),后面随着web应用的发展web应用出现了获取用户状态信息等需求。

以用户登录状态为例,博客的收藏文档需要登录认证才会展现用户自己的收藏文档,那么就需要用户输入账号密码,但是频繁的输入账号密码会影响用户的体验,因此诞生了一次认证,多次使用的需求。

解决思路大体是服务端认证成功后,随机生成字符串,交给浏览器;之后浏览器访问都带上这个字符串交由服务端认证,认证通过则判定为已登录状态,无需多次输入账号密码。

cookie和session就是具体的解决方案
cookie
服务端保存在客户端浏览器上的信息,其表现形式一般是键值对(可以多个)

session
服务端保存在服务端的信息,其表现形式也是键值对。

session 与 cookie 的区别

session 在服务器端,cookie 在客户端。
session 用户无法查看和修改,cookie 用户可以查看修改。
session 和 cookie 的存储容量不同。
session 的实现依赖于 sessionID,而 sessionID 又存储在 cookie 上,所以,可以这么说:session 是基于 cookie 实现的一种数据存储方式。

Cookie使用

cookie虽然是服务端告知浏览器的需要保存的信息,但浏览器也可以拒绝保存,不过这样会导致利用cookie的网页都将无法正常工作,例如无法记录用户的登录状态

cookie的设置
django的视图函数,其返回值都是基类HttpResponseBase的对象,该对象存在设置cookie的方法:set_cookie(),通过该方法我们可以为django 的每一次返回都附件cookie信息。

在设置cookie的时候可以添加一个超时时间
obj.set_cookie(‘username’, ‘jason666’,max_age=3,expires=3)

max_age
expires
	两者都是设置超时时间的 并且都是以秒为单位
	需要注意的是 针对IE浏览器必需使用expires

过期的cookie将会被浏览器清除

cookie的获取
浏览器保存cookie后,每次访问服务端都会带上cookie,django后端可以通过request.COOKIES.get(key)获取浏览器传来的cookie。依次进行认证。

cookie的删除
obj.delete_cookie(key),多用于类似退出登录这样的场景

cookie的应用实例

需求:

设计一个web系统该系统有一个登录页面和若干个业务页面。
只有在登录认证过的状态下才能访问业务页面,否则都跳转到登陆页面。
跳转到登录并认证通过后,就能跳转到之前欲访问的目标页面。

登录页面文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>请登录</h1>
<form action="" method="post">
    用户<input type="text" name="username">
    密码<input type="text" name="passwd">
    <input type="submit">
</form>

</body>
</html>

视图层代码:

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.

def login_auth(func):
    def inner(request,*args,**kwargs):
        cookie=request.COOKIES.get('panks')
        if cookie:
            return func(request)
        else:
            print(request.get_full_path_info())
            dest=request.get_full_path_info()
            return redirect('/login?next=%s'%dest)
    return inner

def login(request):
    if request.method=='POST':
        username=request.POST.get('username')
        passwd = request.POST.get('passwd')

        if username=='panks' and passwd=='321':
            dest=request.GET.get('next')
            if dest:
                obj=redirect(dest)
            else:
                obj=redirect('/home')
            obj.set_cookie('panks','321')
            return obj
    return render(request, 'app01/login.html')

@login_auth
def index(request):
    return HttpResponse('这里是首页')

@login_auth
def home(request):
    return HttpResponse('这里是家目录')

上诉例子主要为了演示效果,实现对cookie认证来通过用户的登录认证,标记用户的状态为已登记,而对于cookie是认证没有太严谨。

实际项目中可以随机生成字符串代替上面的‘321’来设置cookie,并在cookie存储在redis等第三方数据库中,在执行login_auth时,可以从redis中取出原值对客户端提交的cookie进行校验。

session使用

session数据是保存在服务端的(在django框架中默认保存在数据库中)

返回给客户端的是一个随机字符串,客户端该随机字符串在服务端中以为session_key为键存储。

session的作用和cookie类似,用于分辨发起本次请求的用户状态。

在默认情况下django会自动创建django_session用于记录session数据,该表有三个字段:
session_key
服务端针对(没有带cookie或者cookie所对应的session已经过期又或者cookie查找不到对应session)的请求生成的一个随机字符串座位session_key,并以sessionid为键以该随机字符串为值组成一个cookie交给客户端;

session_data
暂时理解为后端设置的session键值对加密后的所得的字符串

expire_date
表示该session数据的过期时间,django默认session的过期时间是14天,但是你也可以人为的修改它

设置session
request.session[‘key’] = value

django内部流程:

  1. django内部生成一个随机字符串,名为session_key也可以叫sessionid
  2. django内部将随机字符串和对应的数据(session设置的键值对加密后得到)存储到django_session表中
    2.1先在内存中产生操作数据的缓存
    2.2在准备响应结果时,django中间件将session数据写入操作数据库
  3. 将产生的随机字符串返回给客户端浏览器以cookie的形式保存
    在这里插入图片描述

获取session
request.session.get(‘key’)

django内部流程:

  1. 自动从浏览器请求中获取sessionid对应的随机字符串
  2. 拿着该随机字符串去django_session表中查找对应的数据(条件为sessionid=session_key)
  3. 如果比对上了 则将对应的session_data数据取出并以字典的形式封装到request.session中,通过request.session.get()取出值
    如果比对不上 则request.session.get()默认返回的是None

设置过期时间
request.session.set_expiry(),括号内可以放四种类型的参数:

 1. 整数				 多少秒
 2. 日期对象			 到指定日期就失效
 3. 0				 一旦当前浏览器窗口关闭立刻失效
 4. 不写				 失效时间就取决于django内部全局session默认的失效时间

清除session
request.session.delete() # 只删服务端的 客户端的不删
request.session.flush() # 浏览器和服务端都清空(推荐使用)

session是保存在服务端的 但是session的保存位置可以有多种选择
1.MySQL
2.文件
3.redis
4.memcache

一个计算机上(IP地址)的一个浏览器只会有一条session数据生效

当session过期的时候可能会出现多条数据对应一个浏览器,但是该现象不会持续很久,内部会自动识别过期的数据清除 你也可以通过代码清除,主要是为了节省服务端数据库资源

session的应用示例

利用session机制重写cookie应用示例,需求不变,故前端代码无需变动,重写视图层

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.

def login_auth(func):
    def inner(request,*args,**kwargs):
        sessionId=request.session.get('panks')
        print(sessionId)
        if sessionId:
            return func(request)
        else:
            print(request.get_full_path_info())
            dest=request.get_full_path_info()
            return redirect('/login?next=%s'%dest)
    return inner

def login(request):
    if request.method=='POST':
        username=request.POST.get('username')
        passwd = request.POST.get('passwd')

        if username=='panks' and passwd=='321':
            dest=request.GET.get('next')
            if dest:
                obj=redirect(dest)
            else:
                obj=redirect('/home')

            request.session['panks']=321
            return obj
    return render(request, 'app01/login.html')

@login_auth
def index(request):
    return HttpResponse('这里是首页')

@login_auth
def home(request):
    return HttpResponse('这里是家目录')

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值