Django cookie 与 session

Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。

识别返回用户包括三个步骤:

  • 服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。
  • 浏览器将这些信息存储在本地计算机上,以备将来使用。
  • 当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。

HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:

Cookies

一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别。

在Web开发中,使用 session 来完成会话跟踪,session 底层依赖 Cookie 技术。

设置 cookie:

复制代码
rep.set_cookie(key,value,...) 
rep.set_signed_cookie(key,value,salt='加密盐',...)

获取 cookie:

复制代码
request.COOKIES.get(key)

删除 cookie:

复制代码
rep =HttpResponse || render || redirect 
rep.delete_cookie(key)

创建应用和模型

models.py

class UserInfo(models.Model):

username = models.CharField(max_length=32)

password = models.CharField(max_length=64)

urls.py

from django.contrib import admin

from django.urls import path

from cookie import views

urlpatterns = [

path('admin/', admin.site.urls),

path('login/', views.login),

path('index/', views.index),

path('logout/', views.logout),

path('order/', views.order)

views.py

def login(request):

if request.method == "GET":

return render(request, "login.html")

username = request.POST.get("username")

password = request.POST.get("pwd")

user_obj = models.UserInfo.objects.filter(username=username, password=password).first()

print(user_obj.username)

if not user_obj:

return redirect("/login/")

else:

rep = redirect("/index/")

rep.set_cookie("is_login", True)

return rep

def index(request):

print(request.COOKIES.get('is_login'))

status = request.COOKIES.get('is_login') # 收到浏览器的再次请求,判断浏览器携带的cookie是不是登录成功的时候响应的 cookie

if not status:

return redirect('/login/')

return render(request, "index.html")

def logout(request):

rep = redirect('/login/')

rep.delete_cookie("is_login")

return rep # 点击注销后执行,删除cookie,不再保存用户状态,并弹到登录页面

def order(request):

print(request.COOKIES.get('is_login'))

status = request.COOKIES.get('is_login')

if not status:

return redirect('/login/')

return render(request, "order.html")

以下创建三个模板文件:login.html、index.html、order.html。

login.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>用户登录</h3> <form action="" method="post"> {% csrf_token %} <p>用户名: <input type="text" name="username"></p> <p>密码: <input type="password" name="pwd"></p> <input type="submit"> </form> </body> </html>

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>index 页面。。。</h2> <a href="/logout/">注销</a> </body> </html>

order.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>order 页面。。。</h2> <a href="/logout/">注销</a> </body> </html>

运行结果如下图所示:

Session(保存在服务端的键值对)

服务器在运行时可以为每一个用户的浏览器创建一个其独享的 session 对象,由于 session 为用户浏览器独享,所以用户在访问服务器的 web 资源时,可以把各自的数据放在各自的 session 中,当用户再去访问该服务器中的其它 web 资源时,其它 web 资源再从用户各自的 session 中取出数据为用户服务。

工作原理

  • a. 浏览器第一次请求获取登录页面 login。

  • b. 浏览器输入账号密码第二次请求,若输入正确,服务器响应浏览器一个 index 页面和一个键为 sessionid,值为随机字符串的 cookie,即 set_cookie ("sessionid",随机字符串)。

  • c. 服务器内部在 django.session 表中记录一条数据。

    django.session 表中有三个字段。

    • session_key:存的是随机字符串,即响应给浏览器的 cookie 的 sessionid 键对应的值。
    • session_data:存的是用户的信息,即多个 request.session"key"=value,且是密文。
    • expire_date:存的是该条记录的过期时间(默认14天)
  • d. 浏览器第三次请求其他资源时,携带 cookie :{sessionid:随机字符串},服务器从 django.session 表中根据该随机字符串取出该用户的数据,供其使用(即保存状态)。

注意: django.session 表中保存的是浏览器的信息,而不是每一个用户的信息。 因此, 同一浏览器多个用户请求只保存一条记录(后面覆盖前面),多个浏览器请求才保存多条记录。

cookie 弥补了 http 无状态的不足,让服务器知道来的人是"谁",但是 cookie 以文本的形式保存在浏览器端,安全性较差,且最大只支持 4096 字节,所以只通过 cookie 识别不同的用户,然后,在对应的 session 里保存私密的信息以及超过 4096 字节的文本。

session 设置:

复制代码
request.session["key"] = value

执行步骤:

  • a. 生成随机字符串
  • b. 把随机字符串和设置的键值对保存到 django_session 表的 session_key 和 session_data 里
  • c. 设置 cookie:set_cookie("sessionid",随机字符串) 响应给浏览器

session 获取:

复制代码
request.session.get('key')

执行步骤:

  • a. 从 cookie 中获取 sessionid 键的值,即随机字符串。
  • b. 根据随机字符串从 django_session 表过滤出记录。
  • c. 取出 session_data 字段的数据。

session 删除,删除整条记录(包括 session_key、session_data、expire_date 三个字段):

复制代码
request.session.flush()

删除 session_data 里的其中一组键值对:

复制代码
del request.session["key"]

执行步骤:

  • a. 从 cookie 中获取 sessionid 键的值,即随机字符串

  • b. 根据随机字符串从 django_session 表过滤出记录

  • c. 删除过滤出来的记录

    补充讲解

    cookie 客户端浏览器上的键值对----为了做会话保持

    复制代码
      -怎么来的? 服务端写入的---》'服务端再返回的响应头中写入,
       即在响应头中会存在cookie的键值对---》浏览器会自动取出来--》
      存起来'-key value 形式--》过期时间---》path---》http only等参数。。。
      
      -只要浏览器中有cookie,再次向当前域发送请求,都会自动携带
      	-携带在 请求头中得 cookie字段中
          cookie:"name=rwf;age=19"
          
          
      -不安全问题---》cookie中发了敏感数据---》客户能看到
      
      
      -cookie设置:  obj.set_cookie()
      -cookie取值:  request.COOKIES.get('键值对的key')
      -清空:        request.COOKIES.clear()
      
      第一次请求后端的时候,会在响应头中返回cookie,后续访问的时候,会在请求头中携带cookie

    我们需要让cookie变的安全---》敏感数据不在cookie中方法,而放在session中,cookie中放sessionid和随机字符串的键值对,所以要使用session就必须使用cookie,就是说,不直接将信息存在cookie中,而实将信息对应的随机字符串存进cookie中

    复制代码
      -session是服务端的键值对
      -session跟cookie有什么关系呢?
      	{随机字符串1:{name:lqz,age:19,password:123},随机字符串2:{name:zs,age:19,password:666}}
      -把key,以cookie的形式,存到浏览器中
      	sessionid:随机字符串1
      -当前浏览器以后再发请。就会携带 过来
      -我们根据带过来的cookie 111----》 从 session中取出对应的数据

    session的使用---》必须要先迁移表---》否则会报django-session表不存在的错误,

    是因为django中默认将session存在数据库中,可以自己改为存在文件或者缓存中
    -session存在服务端的---》默认情况下存在---》django-session表中
    -配置文件
    -django项目有两套配置文件:内置一套,项目自己一套,优先用项目的配置文件
    然后用内置的
    -SESSION_ENGINE = 'django.contrib.sessions.backends.db'

    django-session表的字段

    session_key: sessionid:随机字符串
    session_data: 真正的数据--->加密了
    expire_date: 过期时间

    session的使用

    复制代码
      取值:request.session.get()
      赋值:request.session['name']='rwf'

    session的本质执行原理

    复制代码
      '''
      1 咱们写了request.session['name']='rwf',本质就是向session 对象中放入了name=rwf这个属性
      2session中间件中的process_process函数执行这个操作 
      当前视图函数结束-----》经过 【中间件】 ---》返回给了前端
          -django 内置了一个session中间件
          -判断:request.session 有没有变化,如果有变化
              - 情况一:django-session表中没有数据
                  在表中创建出一条数据,随机生成一个字符串[随机字符串session_key],把数据存入django-session表
                  session_key:随机字符串
                  session_data: name=lqz  加密后存到里面
                  把随机字符串写入到cookie中  :sessionid:随机字符串
              - 情况二:django-session表中有数据
                  把session中所有的值--》加密后--》更新到django-session表的session_data中,其他不变
      3 session中间件中的process_request函数执行这个操作
      下次 再发请求进入任意视图函数---》又会经过  【中间件】---》视图函数
          -视图函数中取session:request.session.get('age')
          -浏览器发请求---》携带cookie过来---》到了中间件---》根据sessionid取出随机字符串
          -拿着随机字符串去django-session中查【session_key】---》 能查到就把 session_data的数据解密---》放到request.session中,类似与一个字典,就可以直接在试图函数中取了
          -后续视图函数中,才能取出值
    
    
      '''

    session的中间件把上述内容完成了:procee_request process_response

    django.contrib.sessions.middleware.SessionMiddleware

    配置session 存放路径(未完成,需要你完成)

    DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'
    SESSION_FILE_PATH='c://xxx/x'
    SESSION_COOKIE_NAME = 'xxx'
    from django.conf import settings
    from django.contrib.sessions.backends import

实例

创建路由:

urls.py

from session import views as session_views

urlpatterns = [

path('session_login/', session_views.login),

path('s_index/', session_views.s_index),

path('s_logout/', session_views.s_logout),

]

创建视图函数:

views.py

def login(request):

if request.method == "GET":

return render(request, "login.html")

username = request.POST.get("username")

password = request.POST.get("pwd")

user_obj = models.UserInfo.objects.filter(username=username, password=password).first()

print(user_obj.username)

if not user_obj:

return redirect("/session_login/")

else:

request.session'is_login' = True

request.session'user1' = username

return redirect("/s_index/")

def s_index(request):

status = request.session.get('is_login')

if not status:

return redirect('/session_login/')

return render(request, "s_index.html")

def s_logout(request):

del request.session"is_login" # 删除session_data里的一组键值对

request.session.flush() # 删除一条记录包括(session_key session_data expire_date)三个字段

return redirect('/session_login/')

模板文件:

s_index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>session_index 页面。。。{{ request.session.user1 }}</h2> <a href="/s_logout/">注销</a> </body> </html>

运行结果如下图所示:

相关推荐
hanxiuchao3 天前
告别客户端臃肿!网页端 M3U8 播放调试方案,适配全办公场景
运维·python·django·m3u8·m3u8播放
程序员羽痕3 天前
基于深度学习的眼疾识别系统
人工智能·pytorch·深度学习·分类·django
流云鹤4 天前
1. 配置环境、创建导航栏
python·django
流云鹤4 天前
2.登录模块
python·django
流云鹤4 天前
专题栏说明
python·django
XGeFei5 天前
【Django学习笔记】—— Django 高并发通俗讲解
笔记·学习·django
weixin_BYSJ19875 天前
springboot美食食谱小程序---附源码24044
java·spring boot·python·spring cloud·django·tomcat·php
许彰午6 天前
87_Python Django模型与数据库
数据库·python·django
weixin_BYSJ19876 天前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
Database_Cool_8 天前
RAG 混合检索首选:阿里云 Lindorm 向量+全文一体化检索
数据库·阿里云·django·云计算