Django(九、cookie与session)

文章目录

一、cookie与session的介绍

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

HTTP四大特性

1.基于请求响应

2.基于TIC、IP作用于应用层上的协议

3.无状态

保存客户端的装态

4.无连接

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

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

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

保存在客户端,与用户状态相关的信息,这种信息都可以叫做cookie

最开始的cookie非常的不安全

session

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

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

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

Django操作cookie

在Django中如何是用cookie

三板斧

python 复制代码
return HttpResponse  返回字符串
return render  返回网页
return redirect  重定向


obj = HttpResponse 
return obj

obj = render
return obj

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

基于cookie的登录功能

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

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

python 复制代码
class Userinfo(models.Model):
    name = models.CharField(max_length=32)
    password = models.IntegerField()

tests.py 创建一些数据出来

python 复制代码
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)

views.py 登录功能

python 复制代码
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

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

这样一个简单的登录功能就创建出来了,这个我们就可以在浏览器里看到cookie已经保存了一些数据

还可以做一个登录验证功能,登录之后才能看到内容,这里用到了装饰器

views.py

python 复制代码
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

python 复制代码
obj.delete_cookie('username')

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

设置cookie参数

python 复制代码
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.comwww2.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. 会生成一个随机字符串
python 复制代码
def set_session(request):
   ![在这里插入图片描述](https://img-blog.csdnimg.cn/6bf1fb0033c44743a9713cd90627c514.png)
 request.session['username'] = 'kevin1'
    return HttpResponse('set_session')
  1. 会把用户设置的信息保存到django_session中,数据也做了加密处理

  2. 把数据封装到了request.session里去了

  3. Django后端把随机字符串保存到浏览器中

  4. 后端的随机字符串中的也保存在浏览器中key=sessionid

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

获取session
python 复制代码
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
python 复制代码
request.session.delete()  # 清空session,只删除服务端的数据,不删除浏览器的
request.session.flush()  # 清空前后端的session数据
session相关的参数
python 复制代码
request.session.values()  # 拿出所有的value值
request.session.keys()  # 拿出所有的key值
request.session.items()  # 拿出所有的key值和value值
设置过期时间
python 复制代码
request.session.set_expiry(value)

如果value是个整数,session会在这些秒数后失效

如果value是个datatime或timedelta,session就会在这个时间后失效。

如果value是0,用户关闭浏览器session就会失效

如果value是None,session会依赖全局session失效策略

CBV添加装饰器

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

第一种

python 复制代码
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')

第二种

python 复制代码
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')

第三种

python 复制代码
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')

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

相关推荐
Java技术小馆22 分钟前
AI模型统一接口桥接工具
后端·程序员
华仔啊38 分钟前
Docker入门全攻略:轻松上手,提升你的项目效率
后端·docker·容器
2401_831501731 小时前
Python学习之Day07-08学习(Django网页Web开发)
python·学习·django
IT_陈寒1 小时前
Redis性能翻倍秘籍:10个99%开发者不知道的冷门配置优化技巧
前端·人工智能·后端
Tiny番茄1 小时前
leetcode 3. 无重复字符的最长子串
数据结构·python·算法·leetcode
洛小豆1 小时前
Swagger3学习与实践指南
spring boot·后端·spring cloud
Victor3561 小时前
Redis(58)如何配置和查看Redis的慢查询日志?
后端
Victor3561 小时前
Redis(59)Redis的主从复制是如何实现的?
后端
胡斌附体1 小时前
离线docker安装jupyter(python网页版编辑器)
python·docker·jupyter·image·tar·save
摇滚侠2 小时前
Spring Boot 3零基础教程,自动配置机制,笔记07
spring boot·笔记·后端