zoukankan      html  css  js  c++  java
  • Django之cookie与session

    Django之Cookie与Session

      Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道。

      因为HTTP协议是无状态的,即每次用户请求到达服务器时,HTTP服务器并不知道这个用户是谁、是否登录过等。现在的服务器之所以知道我们是否已经登录,是因为服务器在登录时设置了浏览器的Cookie!Session则是借由Cookie而实现的更高层的服务器与浏览器之间的会话。

    Cookie

    概念

      Cookie是由客户端保存的小型文本文件,其内容为一系列的键值对。 Cookie是由HTTP服务器设置的,保存在浏览器中, 在用户访问其他页面时,会在HTTP请求中附上该服务器之前设置的Cookie。

    传递流程

    1. 浏览器向某个URL发起HTTP请求(可以是任何请求,比如GET一个页面、POST一个登录表单等)
    2. 对应的服务器收到该HTTP请求,并计算应当返回给浏览器的HTTP响应。
    3. 在响应头加入set-cookie字段,它的值是要设置的Cookie。
      UserAgent(浏览器就是一种用户代理)至少应支持300项Cookie, 每项至少应支持到4096字节,每个域名至少支持20项Cookie
    4. 浏览器收到来自服务器的HTTP响应。
    5. 浏览器在响应头中发现set-cookie字段,就会将该字段的值保存在内存或者硬盘中。
      set-cookie字段的值可以是很多项Cookie,每一项都可以指定过期时间Expires默认的过期时间是用户关闭浏览器时。
    6. 浏览器下次给该服务器发送HTTP请求时, 会将服务器设置的Cookie附加在HTTP请求的头字段Cookie中。
      浏览器可以存储多个域名下的Cookie,但只发送当前请求的域名曾经指定的Cookie, 这个域名也可以在set-cookie字段中指定。
    7. 服务器收到这个HTTP请求,发现请求头中有Cookie字段, 便知道之前就和这个用户打过交道了。
    8. 过期的Cookie会被浏览器删除。

      服务器通过set-cookie响应头字段来指示浏览器保存Cookie, 浏览器通过Cookie请求头字段来告诉服务器之前的状态。 Cookie中包含若干个键值对,每个键值对可以设置过期时间。  

    作用

      HTTP协议是无状态的,每次请求都是无关联的,没有办法保存状态,所以使用Cookie保存状态。

    特性

      服务器让浏览器保存的Cookie。

      浏览器有权拒绝保存Cookie,但是当浏览器拒绝保存Cookie时,就无法完成Web登录。

    应用

      web登录、习惯记录、投票等。

    缺点

      Cookie长度有限,能保存的数据量有限。

      Cookie保存在本地,导致数据不安全。

    使用

      由于Cookie以字典的形式保存,所以使用操作字典的方式来操作Cookie。

    设置Cookie

      普通设置,key为键,value为值,max_age为后台控制过期时间。

    ret = HttpResponse('xxoo')
    ret.set_cookie(key, value, max_age=5)

    设置加密Cookie

      salt为设置加密用的盐。

    ret = HttpResponse('xxoo')
    ret.set_signed_cookie(key, max_age=5, salt='xxoo')

      Cookie可以设置多个参数,具体参数关键字如下:

    key
    value=''
    max_age=None 超时时间
    ecpires=None 超时时间(IE requires expires, so set it if hasn't been already.)
    path='/' Cookie生效的路径,/表示根路径,特殊的:根路径的Cookie可以被任何url的页面访问
    domain=None Cookie生效的域名
    secure=False HTTPS传输协议的使用与否
    httponly=False 只能HTTP协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到,也可以被覆盖)

     

    获取Cookie

      获取普通方式设置的Cookie

        方法一:

    request.COOKIES['is_login']  # 假设is_login为之前设置的key

        方法二:

    request.COOKIES.get('is_login')  # 假设is_login为之前设置的key

      获取加盐设置的Cookie

    request.get_signed_cookie(key, salt='xxoo', default='')

      其中default为默认值。

    删除cookie

    ret.delete_cookie(key)  # key 为之前设置的键

    Django框架中的使用示例之Cookie版登录

    from django.shortcuts import render, redirect
    from django.views import View
    
    # Create your views here.
    def login_required(fn):
        """
        装饰器,在登陆之前验证Cookie
        """
    
        def inner(request, *args, **kwargs):
    
            if request.COOKIES.get('is_login') != '1':  # 判断Cookie的值是否为之前设定的值
                next = request.path_info  # 获取url端口号之后的其他路径信息
    
                return redirect(f'/login/?next={next}')  # 将获取到的路径信息拼接到login之后跳转到login路由
    
            ret = fn(request, *args, **kwargs)
    
            return ret
    
        return inner
    
    
    class Login(View):
    
        def get(self, request):
    
            return render(request, 'login.html')
    
        def post(self, request):
            user = request.POST.get('user')  # 获取用户填写的用户名
            pwd = request.POST.get('pwd')  # 获取用户填写的密码
    
            if user == 'a' and pwd == '1':  # 判断用户名与密码的正确性
                next = request.GET.get('next')  # 获取login后面拼接的路径信息
                if next:  # 判断是否有拼接路径
                    ret = redirect(next)  # 跳转到拼接的路径路由上
                else:
                    ret = redirect('/index/')  # 跳转到index路由上
                ret.ret_cookie['is_login'] = '1'  # 设置Cookie的值
    
                return ret
    
            else:
    
                return redirect('/login/')  # 登录失败跳转到登录页面重新登录
    
    
    @login_required
    def index(request):
    
        return  render(request, 'index.html')
    
    
    @login_required
    def home(request):
    
        return render(request, 'home.html')
    
    
    def logout(request):
        ret = redirect('/login/')
        request.delete_cookie('is_login')  # 注销删除Cookie
    
        return ret

    Session

    概念

       保存在服务器上的一组组键值对,与Cookie搭配使用。

    作用

      Cookie保存在浏览器本地,容易非法获取,不安全;而session是保存在服务器上,数据安全。

      Cookie的长度受到限制,而session是经过加密换算得到的结果,不受长度限制。

    Django中的使用

    设置Session

      方法一:

    request.session[key] = value

      方法二:

    request.session.setdefault(key, value)

    获取Session

      方法一:

    request.session[key]

      方法二:

    request.session.get(key)

    删除Session

      删除某一个(指定)键值对

    del request.session[key]

      删除该用户的所有的Session数据,不删除Cookie

    request.session.delete()

      删除该用户的所有的Session数据,删除Cookie

    request.session.flush

    设置超时时间

    request.session.set_expiry()

    清除所有过期的Session

    request.session.clear_expired()

    配置

    Session的表名

    # Cookie name. This can be whatever you want.
    SESSION_COOKIE_NAME = 'sessionid'  # 默认的表名为sessionid

    超时时间

    # Age of cookie, in seconds (default: 2 weeks).
    SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2  # 默认超时时间为两周

    每次都改变Session的值   # 是否在每个请求中保存会话数据。

    # Whether to save the session data on every request.
    SESSION_SAVE_EVERY_REQUEST = False

    当Web浏览器关闭时,用户的会话Cookie是否过期。

    # Whether a user's session cookie expires when the Web browser is closed.
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False

    设置数据库引擎

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'

    注意

      使用Session时,app文件夹和中间件中都要有Session的配置参数。

      服务器只认浏览器,不认用户,当用户发生改变时,或覆盖之前的值,key不变。

      同一个浏览器(本地),登录同一个账号,服务器中存储的内容不变。

      关闭浏览器失效的是本地浏览器中的cookie。

    Django框架中的使用示例之Session登录

    from django.shortcuts import render, redirect
    from django.views import View
    
    # Create your views here.
    def login_required(fn):
        """
        装饰器,在登陆之前验证session
        """
    
        def inner(request, *args, **kwargs):
    
            if request.session.get('is_login') != '1':  # 判断session的值是否为之前设定的值
                next = request.path_info  # 获取url端口号之后的其他路径信息
    
                return redirect(f'/login/?next={next}')  # 将获取到的路径信息拼接到login之后跳转到login路由
    
            ret = fn(request, *args, **kwargs)
    
            return ret
    
        return inner
    
    
    class Login(View):
    
        def get(self, request):
    
            return render(request, 'login.html')
    
        def post(self, request):
            user = request.POST.get('user')  # 获取用户填写的用户名
            pwd = request.POST.get('pwd')  # 获取用户填写的密码
    
            if user == 'a' and pwd == '1':  # 判断用户名与密码的正确性
                next = request.GET.get('next')  # 获取login后面拼接的路径信息
                if next:  # 判断是否有拼接路径
                    ret = redirect(next)  # 跳转到拼接的路径路由上
                else:
                    ret = redirect('/index/')  # 跳转到index路由上
                ret.session['is_login'] = '1'  # 设置session的值
    
                return ret
    
            else:
    
                return redirect('/login/')  # 登录失败跳转到登录页面重新登录
    
    
    @login_required
    def index(request):
    
        return  render(request, 'index.html')
    
    
    @login_required
    def home(request):
    
        return render(request, 'home.html')
    
    
    def logout(request):
        ret = redirect('/login/')
        request.session.flush()  # 注销删除session信息和cookie值
    
        return ret

    参考文章

    Cookie/Session的机制与安全

  • 相关阅读:
    关于MyEclipse项目的名字的修改对项目导入导出的影响
    关于SQL语句的一些注意事项
    关于Struts2的jsp页面的注释
    关于VS2013常用到的快捷键
    关于Cocos2d-x中定时器的使用总结
    关于Cocos2d-x中打包图集和使用方法
    zend studio 10.6.2 设置默认编码为UTF-8
    zend studio 10.6.2 字体大小 设置
    zend Studio10.6.2汉化
    JQ Ajax 上传文件
  • 原文地址:https://www.cnblogs.com/ZN-225/p/9792259.html
Copyright © 2011-2022 走看看