Cookie和session

Posted zgf-666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie和session相关的知识,希望对你有一定的参考价值。

       Cookie    

在一个会话的多个请求中共享数据,就是会话跟踪技术

HTTP协议是无状态协议,每个请求都是独立的!无法记录前一次请求的状态。
但HTTP协议中可以使用Cookie来完成会话跟踪!
在Web开发中,使用session来完成会话跟踪,session底层依赖Cookie技术

Cookie的概念:

Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对

Cookie的原理:

1.客户端向服务端发送请求,第一次的值为空 cookie:{}
2.服务端接受请求后,设置cookie,request.set_cookie(key,value,),随着响应发给浏览器
3.客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器
当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

Cookie与HTTP头 :

Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:
1.客户端请求:
请求头中携带Cookie:{key,value}
格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开
2.服务端响应:
响应头中携带Set-Cookie:{key,value}
一个Cookie对象一个Set-Cookie:
Set-Cookie:a=A Set-Cookie: b=B Set-Cookie: c=C
如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,
那么客户端只留下一个Cookie,即:a=AA。

1.设置Cookie

rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt=加密盐,...) 加密
return rep

2.获取cookie

request.COOKIES.get("is_login")
request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None)

3.删除Cookie

def logout(request):
    # 如何删除Cookie
    rep = redirect("/login/")
    rep.delete_cookie("is_login")
    return rep

简单的cookie操作

技术分享图片
def login(request):
    if request.method=="POST":
        name=request.POST.get("username")
        passwd=request.POST.get("password")
        if name=="jerd" and passwd=="123":
            ##使用cookie,让浏览器保存一个键值对
            rep=redirect("/home/")
            # rep.set_cookie("is_login","1")  #明文
            ##使用密文##
            rep.set_signed_cookie("is_login","1",salt="jerd")
            return rep
    return render(request,"login.html")
def home(request):
    ##进行判断,如果登录成功就能进入到家目录,没登录,就去登录
    # ret=request.COOKIES.get("is_login")  #传过来的是字符串
    ret=request.get_signed_cookie("is_login",default=0,salt="jerd")
    if ret=="1":
        return render(request, "home.html")
    else:
        return render(request, "login.html")
View Code

使用装饰器

技术分享图片
def is_login(func):
    def inner(request,*args,**kwargs):
        ret=request.get_signed_cookie("is_login",default=0,salt="jerd")
        if ret == "1":
            return func(request,*args,**kwargs)
        else:
            return render(request,"login.html")
    return inner
@is_login
def index(request):
    return render(request, "index.html")
View Code

Cookie版登陆校验

技术分享图片
如果是从其他页面跳转到登录页面,在登录成功后,跳转到之前的页面
from functools import wraps
def is_login(func):
    @wraps(func) # 装饰器修复技术
    def inner(request,*args,**kwargs):
        ret=request.get_signed_cookie("is_login",default=0,salt="jerd")
        if ret == "1":
            return func(request,*args,**kwargs)
        else:
            now_url=request.path_info #获取当前访问的url
            return redirect("/login/?next={}".format(now_url))
    return inner
def login(request):
    print("-" * 120)
    print(request.get_full_path())  # 获取当前请求的路径和参数
    print(request.path_info)  # 取当前请求的路径
    print("-" * 120)
    if request.method=="POST":
        name=request.POST.get("username")
        passwd=request.POST.get("password")
        next_url = request.GET.get("next")  # 从URL里面取到 next 参数
        print(next_url)
        if name=="jerd" and passwd=="123":
            ##使用cookie,让浏览器保存一个键值对
            ##如果是从其他页面跳转到登录页面,在登录成功后,跳转到之前的页面
           if next_url:
               rep = redirect(next_url)
            #直接进登录页面,登陆后,默认跳到home页面
           else:
                rep=redirect("/home/")
            # rep.set_cookie("is_login","1")  #明文
            ##使用密文 一周有效##
           rep.set_signed_cookie("is_login", "1", salt="jerd",max_age=7*24*60*60)
           return rep
    return render(request,"login.html")
def home(request):
    ##进行判断,如果登录成功就能进入到家目录,没登录,就去登录
    # ret=request.COOKIES.get("is_login")  #传过来的是字符串
    ret=request.get_signed_cookie("is_login",default=0,salt="jerd")
    if ret=="1":
        return render(request, "home.html")
    else:
        return render(request, "login.html")
@is_login
def index(request):
    return render(request, "index.html")
##删除cookie##
def logout(request):
    rep=redirect("/login/")
    rep.delete_cookie("is_login")
    return rep
在登录页面中,就不能再提交给login
{#从其他页面跳到登录页面时,此时login后面带有参数,提交时就不能再提交给login#}
{#<form action="/login/" method="post">#}
<form action="{{ request.get_full_path }}" method="post">
View Code

   Session  

Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;但是Cookie本身保存在客户端,可能被拦截或窃取,自身安全性较差;
而Session保存在服务器,有较高的安全性。
所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息
session的特性:
Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,
由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,
当用户再去访问该服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
技术分享图片

 

技术分享图片

技术分享图片

常用操作:

1.设置session: request.session["is_login"]="1"
    2.获取session: request.session.get(""is_login")
    3.只删除session数据  request.session.delete()
    4.删除session数据和cookie request.session.flush()
    5.设置会话Session和Cookie的超时时间
        request.session.set_expiry(value) 
        * 如果value是个整数,session会在些秒数后失效。 cookie值消失
        * 如果value是个datatime或timedelta,session就会在这个时间后失效。
        * 如果value是0,用户关闭浏览器session就会失效。
        * 如果value是None,session会依赖全局session失效策略。
   6.在setting中添加
      SESSION_SAVE_EVERY_REQUEST =True  每次请求都保存Session
设置完之后,在网页删访问改,会失败。原因是session产生数据没存到数据库中,
配置完数据库,使用makemigrations和migrate后,数据库中会泽东生成一张session表,存放着k和data
Session版登陆验证
技术分享图片
from functools import wraps
def is_login(func):
    @wraps(func) # 装饰器修复技术
    def inner(request,*args,**kwargs):
        ret=request.session.get("is_login")
        #获取时的流程##
        # 1. 获取cookie中的随机字符串
        # 2. 根据随机字符串去数据库取 session_data --> 解密 --> 反序列化成字典
        # 3. 在字典里面 根据 is_login 取具体的数据
        if ret == "1":
            return func(request,*args,**kwargs)
        else:
            now_url=request.path_info #获取当前访问的url
            return redirect("/login/?next={}".format(now_url))
    return inner
def login(request):
    print("-" * 120)
    print(request.get_full_path())  # 获取当前请求的路径和参数
    print(request.path_info)  # 取当前请求的路径
    print("-" * 120)
    if request.method=="POST":
        name=request.POST.get("username")
        passwd=request.POST.get("password")
        next_url = request.GET.get("next")  # 从URL里面取到 next 参数
        if name=="jerd" and passwd=="123":
           if next_url:
               rep = redirect(next_url)
            #直接进登录页面,登陆后,默认跳到home页面
           else:
                rep=redirect("/home/")
           request.session["is_login"]="1"
           ##可以设置多个值,但都存在一个k只 k:{"is_login":"1","name":user}
           request.session.set_expiry(100)  # 100秒钟之后失效
           request.session["name"] = name
           return rep
    return render(request,"login.html")
@is_login
def home(request):
    user=request.session.get("name") #获取到用户名
    return render(request, "home.html",{"username":user})
@is_login
def index(request):
    return render(request, "index.html")
##删除##
def logout(request):
    request.session.flush()
    return redirect("/login/")
View Code

cookie和session总结

1.COOKIE的由来:
因为HTTP请求时没有状态的,每一次请求都是独立的,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
2.cookie就是保存在浏览器上的键值对
服务器控制着相应,在相应里可以让浏览器在本地保存键值对,下次请求再发送的时候就会自动携带这个cookie值。浏览器关闭,cookie就失效
3.cooie的应用:1.七天免登陆 2.记录用户的浏览器习惯 3.简单的投票规则
4.服务端:
1. 生成字符串
2. 随着响应将字符串回复给浏览器
3. 从浏览器发送的请求中拿到字符串
好处:
服务端不用存,减轻了服务器压力
坏处:
信息不安全
session:保存在服务端的键值对,必须依赖于cookie
在服务器端存在的形式 sadsjhsjkcehhw:{"is_login":1,"user":"jerd"}
Django中session的执行存过程:
存session: request.session["is_login"]="1"
1.在服务端生成随机字符串
2.生成一个和上面随机字符串对应的大字典,用来保护疏忽数据
3.随机字符串当成cookie返回给浏览器
存session:ret=request.session.get("is_login")
1.从请求携带的cookie里面找到随机字符串
2.拿到的随机字符串去session中找对应的大字典
3.从大字典中根据key取值
session的优势:
1.比cookie能存的数据多
2.安全性好,数据存在服务端
坏处:
数据都保存在服务端,存储压力比较大
 

























以上是关于Cookie和session的主要内容,如果未能解决你的问题,请参考以下文章

少部分手机浏览器对于COOKIE支持不够导致服务端无法读取session的解决方案

Cookie和Session的工作流程及区别(附代码案例)

cookie和session

cookie和session

cookie和session

会话技术知识点整理(Cookie和Session)