Django(九、cookie与session)

一、cookie与session的介绍

在讲之前我们先来回忆一下HTTP的四大特性

HTTP四大特性

1.基于请求响应
2.基于TIC、IP作用于应用层上的协议
3.无状态
          保存客户端的装态
4.无连接

这篇文章要讲的就是跟“无状态”有关

最开始所有的网站都不需要用户注册登录,所有人来访问到的数据都是一样的

但是随着互联网的发展很多网站需要知道当前用户的状态

在这里插入图片描述

cookie

保存在客户端,与用户状态相关的信息,这种信息都可以叫做cookie
最开始的cookie非常的不安全

session

保存在服务端,与用户状态相关的信息,session依赖于cookie工作

在这里插入图片描述
当然也可以不保存cookie,在浏览器里设置阻止所有cookie,当你设置了以后,所有需要登录的网页都会登录不上去。

原理就是用户登录以后,所有的相关信息都需要经过cookie,服务器需要返回一些数据给cookie,但是你的cookie被你关掉了,就不会验证,也就是令牌没有作用了,所以不简易阻止所有cookie

Django操作cookie

在Django中如何是用cookie

三板斧

return HttpResponse  返回字符串
return render  返回网页
return redirect  重定向


obj = HttpResponse 
return obj

obj = render
return obj

obj = redirect
return obj
操作cookie的时候,就用到了这个obj对象

基于cookie的登录功能

首先我们做一个简单的登录页面功能,需要创建一个数据库,从数据库匹配账户密码

models.py 创建数据库,创建完别忘了做数据迁移

class Userinfo(models.Model):
    name = models.CharField(max_length=32)
    password = models.IntegerField()

tests.py 创建一些数据出来

import os
import sys

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day10.settings')
    import django

    django.setup()
    from app01 import models

    bulk_list = []
    for i in range(10000):
        user_obj = models.Userinfo(name=f'kevin{i}', password=f"{i}")
        bulk_list.append(user_obj)

    models.Userinfo.objects.bulk_create(bulk_list)
set_cookie 设置cookie

views.py 登录功能

def login(request):
    if request.method == 'POST':
        print(request.POST)
        username = request.POST.get('username')  # 这里取到的是前端name的键
        password = request.POST.get('password')
        userinfo = models.Userinfo.objects.all()  # 查询数据库的得到userinfo对象
        for i in userinfo:  # 循环数据库里的数据
            if username == i.name and password == str(i.password):  # 判断数据是否匹配
                print('登录成功')
                obj = redirect('/index/')  # 先实例化对象登录成功跳转页面
                obj.set_cookie('username', i.name, max_age=60)  # 让浏览器记录当前登录状态,max_age=60这条记录只保存60秒,60秒后删除
                return obj  # 登录成功跳转页面
        else:
            return HttpResponse("密码错误")
    return render(request, 'login.html')

login.html

<body>
<form action="" method="post">
    用户名
    <input type="text" name="username">
    密码
    <input type="password" name="password">
    <input type="submit">
</form>
</body>

这样一个简单的登录功能就创建出来了,这个我们就可以在浏览器里看到cookie已经保存了一些数据
在这里插入图片描述
还可以做一个登录验证功能,登录之后才能看到内容,这里用到了装饰器

views.py

def login_auth(func):
    def inner(*args, **kwargs):  # 这里就已经接收到了request参数
        request = args[0]  # 将request从args中索引取值出来
        if request.COOKIES.get('username'):  # 如果cookies有值就不用再登陆
            return func(*args, **kwargs)
        else:                              # 否则需要登录验证
            return redirect('/login/')   # 跳转到登录页面
    return inner


@login_auth  # 添加登录功能装饰器
def index(request):
    if request.is_ajax():
        myfile = request.FILES.get('myfile')
        import os
        dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 获取当前文件所在路径

        with open(dir_path + '/static/' + myfile.name, 'wb') as f:  # 将文件写到static文件夹下
            for i in myfile:
                f.write(i)
    return render(request, 'index.html', locals())

清空cookie

obj.delete_cookie('username')

使用场景:退出登录、注销

设置cookie参数

obj.set_cookie('username', i.name, max_age=60)

上面我们用到了三种参数分别是

● key, 键

● value=’’, 值

● max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止

还有其他的一些参数
● expires=None, 超时时间(IE requires expires, so set it if hasn’t been already.),兼容IE浏览器可以在同时设置两种,这样兼容了所有浏览器

● path=’/‘, Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。

● domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=”.example.com”所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取

● secure=False, 浏览器将通过HTTPS来回传cookie

● httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

Django操作session

session的数据是保存在后端,保存在后端的载体其实有很多种,比如:可以把数据保存在数据库、文件、Redis等

Django的默认保存位置在数据库中,在django_session表中

设置session

成功设置一个seesion值有什么变化:

  1. 会生成一个随机字符串
def set_session(request):
   ![在这里插入图片描述](https://img-blog.csdnimg.cn/6bf1fb0033c44743a9713cd90627c514.png)
 request.session['username'] = 'kevin1'
    return HttpResponse('set_session')

在这里插入图片描述
2. 会把用户设置的信息保存到django_session中,数据也做了加密处理
在这里插入图片描述
3. 把数据封装到了request.session里去了

  1. Django后端把随机字符串保存到浏览器中
  2. 后端的随机字符串中的也保存在浏览器中key=sessionid

这个是候我们再多设置一个值的时候,session_key是不变的,变的是session_data,在别的浏览器打开的是候,会多增加一条,但是一个浏览器只对应一条,这样做的好处可以节省MySQL数据空间

获取session
def get_session(request):
    print(request.session.get('username'))  #kevin1, 直接通过点语法获取
    return HttpResponse('get_session')

获取session的时候发生了哪些事

  1. 浏览器先把sessionid回传到Django的后端

  2. Django后端获取到了sessionid,然后去数据表中根据session_key查询
    如果查到了,就说明之前已经登录过
    如果查不到,就返回None

  3. 查询出来的数据默认是加密的,Django后端又把数据解密之后封装到request.session中
    在取session值的时候,就从request.session中取

  4. session的过期时间默认是14天

清空session
request.session.delete()  # 清空session,只删除服务端的数据,不删除浏览器的
request.session.flush()  # 清空前后端的session数据
session相关的参数
request.session.values()  # 拿出所有的value值
request.session.keys()  # 拿出所有的key值
request.session.items()  # 拿出所有的key值和value值
设置过期时间
request.session.set_expiry(value)

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

CBV添加装饰器

现在我给CBV添加一个登录验证,有三种方法

第一种

from django.utils.decorators import method_decorator


@method_decorator(login_auth, name='get')
@method_decorator(login_auth, name='post')
class L_login(View):
    def get(self, *args, **kwargs):
        return HttpResponse('get')

    def post(self, *args, **kwargs):
        return HttpResponse('post')

第二种

from django.utils.decorators import method_decorator


class L_login(View):
    @method_decorator(login_auth)
    def get(self, *args, **kwargs):
        return HttpResponse('get')

    @method_decorator(login_auth)
    def post(self, *args, **kwargs):
        return HttpResponse('post')

第三种

from django.utils.decorators import method_decorator


class L_login(View):
    @method_decorator(login_auth)  # 加载dispatch上的装饰器会对下面的所有方法起作用
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

一般第一种和第二种用的比较多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值