• Django Cookie和Session


    一、cookie和session的介绍

      

      cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。

    cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

    cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。

      问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。

    我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。

    总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。

    另外,上述所说的cookie和session其实是共通性的东西,不限于语言和框架

    二、登录应用原理

      前几节的介绍中我们已经有能力制作一个登陆页面,在验证了用户名和密码的正确性后跳转到后台的页面。但是测试后也发现,如果绕过登陆页面。直接输入后台的url地址也可以直接访问的。这个显然是不合理的。其实我们缺失的就是cookie和session配合的验证。有了这个验证过程,我们就可以实现和其他网站一样必须登录才能进入后台页面了。

          先说一下这种认证的机制。每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证。服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端,这个被存储在浏览端的东西就叫cookie。而服务器端也会自己存储一下用户当前的状态,比如login=true,username=hahaha之类的用户信息。但是这种存储是以字典形式存储的,字典的唯一key就是刚才发给用户的唯一的cookie值。那么如果在服务器端查看session信息的话,理论上就会看到如下样子的字典

    {'123abc':{'login':true,'username:hahaha'}}

      因为每个cookie都是唯一的,所以我们在电脑上换个浏览器再登陆同一个网站也需要再次验证。那么为什么说我们只是理论上看到这样子的字典呢?因为处于安全性的考虑,其实对于上面那个大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在服务器端也是一样被加密的。所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西

    {'123abc':dasdasdasd1231231da1231231}

    三、cookie的简单使用

    获取cookie:如果有值就获取,如果没有则返回None

    val = request.COOKIES.get('user','')

    设置cookie:

    expires:过期时间,是一个日期时间型

    path:有效路径,设置的cookie只作用于这个路径以及子路径

    max_age:过期时间,单位是秒

            response = redirect('/index/')
                # response.set_cookie('is_login',True,max_age=15) #max_age是以秒计算的,不支持ie
                date = datetime.date(year=2020,month=12,day=31)
                response.set_cookie('user',user_ret.name,expires=date,path='/index/') 

    删除cookie:

    response.delete_cookie('user','user_ret.name)

    基于登录验证的3次请求过程:

    一共有三次请求
      注意:form表单的action走的路径还是/login/
         第一次请求:url:http://127.0.0.1:8080/login GET请求
           第二次请求:url:http://127.0.0.1:8080/login POST请求 user pwd
           第三次请求:url:http://127.0.0.1:8080/index GET请求 携带着cookie的了
           所以在index页面中就会取到cookie,因为这是的index里面已经有cookie了

    注意:点击提交时,完成了2次请求,一次是form表单的POST请求,一次是验证成功后return response跳转到index的GET请求

    登录验证代码:

    views.py

    from django.shortcuts import render,HttpResponse,redirect
    from app01.models import *
    import datetime
    import  time
    # Create your views here.
    def login(request):
        if request.method=='POST':
            print('我是post请求')
            user = request.POST.get('user','')
            pwd = request.POST.get('passwd')
            user_ret = Userinfo.objects.filter(name=user,pwd=pwd).first()
            print('用户名:',user)
            print(user_ret)
            if user_ret :
                response = redirect('/index/')
                # response.set_cookie('is_login',True,max_age=15) #max_age是以秒计算的,不支持ie
                response.set_cookie('is_login',True) #max_age是以秒计算的,不支持ie
                date = datetime.date(year=2020,month=12,day=31)
                response.set_cookie('user',user_ret.name,expires=date,path='/index/') #
                # response.set_cookie()
    
                return response
            else:
                return HttpResponse('登录失败')
        print("我是get请求")
        return  render(request,'login.html')
    
    def index(request):
        print('请求类型:',request.method)
        is_login =request.COOKIES.get('is_login')
        if is_login:
            # 登录成功后,取出cookies中设置的user
            username = request.COOKIES.get('user')
            '''显示上次登录时间:
            1,取出上次登录时间last_time,如果没有,则为空
            2,设置这次登录时间login_date
            3,设置这次登录的last_time
            
            '''
            last = request.COOKIES.get('last_time','')  #1
            login_date = time.strftime('%Y-%m-%d %X',time.localtime())#2
            response=render(request,'index.html',{'username':username,'logindate':last})
            response.set_cookie('last_time',login_date)#3
            return response
        else:
            return redirect('/login/')
    
        # return render(request,'index.html')
    View Code

    login.html

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>Cookies设置</title>
    </head>
    <body>
    <form action="" method="post">
        {% csrf_token %}
        用户名 <input type="text" name="user">
        密码 <input type="password" name="passwd">
        <input type="submit">
    
    </form>
    </body>
    </html>
    View Code

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Index</title>
    </head>
    <body>
    <h1>Hi,{{ username }}</h1>
    <h2>上次登录时间:{{ logindate }}</h2>
    </body>
    </html>
    View Code

    cookie存储到客户端

    优点:数据存储在客户端。减轻服务端的压力,提高网站的性能

    缺点:安全性不高,在客户端很容易被查看或破解用户会话信息

     四、session的简单使用

    1、基本操作(需要掌握的)

    1、设置session值
        request.session["session_name"]="admin"
    2、获取session值
        session_name = request.session("session_name")
    3、删除session值
        del request.session["session_name"]  删除一组键值对
        request.session.flush()   删除一条记录
    4、检测是否操作session值
        if "session_name"  in request.session:

    其他操作

    5、get(key, default=None)
     
    fav_color = request.session.get('fav_color', 'red')
     
    6、pop(key)
     
    fav_color = request.session.pop('fav_color')
     
    7、keys()
     
    8、items()
     
    9、setdefault()
     
    10、flush() 删除当前的会话数据并删除会话的Cookie。
                这用于确保前面的会话数据不可以再次被用户的浏览器访问
                例如,django.contrib.auth.logout() 函数中就会调用它。
    用户session的随机字符串
            request.session.session_key
      
            # 将所有Session失效日期小于当前日期的数据删除
            request.session.clear_expired()
      
            # 检查 用户session的随机字符串 在数据库中是否
            request.session.exists("session_key")
      
            # 删除当前用户的所有Session数据
            request.session.delete("session_key")
      
            request.session.set_expiry(value)
                * 如果value是个整数,session会在些秒数后失效。
                * 如果value是个datatime或timedelta,session就会在这个时间后失效。
                * 如果value是0,用户关闭浏览器session就会失效。
                * 如果value是None,session会依赖全局session失效策略。
    View Code

    session配置

    Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
       
    a. 配置 settings.py
       
        SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
           
        SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
        SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
        SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
        SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
        SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
        SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
        SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    使用session技术,首次登录后,会针对客户端(不同的浏览器,就是不同的客户端),生成一个唯一的sessionid
    如果后续使用不同的用户,在相同的客户端(浏览器)登录,那么只会更新session_data中的输入,而不是重新生成sessionid

    session流程解析:
    1,登录成功后,会在服务器上生成session信息,格式为{'key':value}的字典,包括sessionid,session_data,session_expire
    2,生成的sessionid会发送到浏览器上的cookies中,下次登录的时候,浏览器会带着这sessionid发送请求,如果sessionid在服务器中有值(说明还未到过期时间),就可以取出session_data
    3,同一个浏览器(客户端),登录不同的用户,会直接删除掉上一次用户的session信息.但是sessionid不会发生改变

    
    
    
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    质数和分解(完全背包)
    CodeForces
    FZU
    FZU
    Pets(匈牙利算法)
    Construct a Matrix (矩阵快速幂+构造)
    绝世好题(线性dp)
    String painter (区间dp)
    Funny Positive Sequence (思维+前缀)
  • 原文地址:https://www.cnblogs.com/lovepy3/p/10978787.html
Copyright © 2020-2023  润新知