zoukankan      html  css  js  c++  java
  • Django中的Cookie--实现登录

    Django中的Cookie--实现登录

    Cookie

    Cookie 是什么

    保存在浏览器端的键值对,让服务器提取有用的信息。

    为什么要有 Cookie

    因为HTTP请求是无状态的。

    无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。

    状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。

    Cookie 的原理

    服务端可以在返回响应的时候 做手脚
    在浏览器上写入键值对(Cookie)

    浏览器发送请求的时候会自动携带该网站保存在我浏览器的键值对(Cookie)

    Chrome 上查看 Cookie

     

    查看Cookie

     

    Django 中操作 Cookie

    设置 Cookie

    只有响应对象才能设置 Cookie

    # 响应对象
    rep = HttpResponse(...)
    rep = render(request, ...)
    rep = redirect(...)
    
    # 不加密方式设置Cookie
    rep.set_cookie(key,value,...)
    
    # 加密方式设置Cookie
    rep.set_signed_cookie(key,value,salt='加密盐',...)
    

    参数

    • key, 键
    • value='', 值
    • max_age=None, 超时时间
    • expires=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

    1. 不加密的 Cookie 获取:
      request.COOKIES['key']
      request.COOKIES.get('key')
      
    2. 加密的 Cookie 获取
      request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
      
      参数:
      • default: 默认值
      • salt: 加密盐
      • max_age: 后台控制过期时间

    删除 Cookie

    删除 Cookie 操作大多是在注销时用的,也是 通过响应对象删除

    def logout(request):
        # 删除cookie,操作的是响应对象,最后需要返回
        rep = redirect("/app01/login/")
        rep.delete_cookie("is_login")
        return rep
    

    Cookie 版登录代码

    from django.shortcuts import render, redirect
    
    # 导入用于装饰器修复技术的包
    from functools import wraps
    # Create your views here.
    
    
    # 装饰器函数,用来判断是否登录
    def check_login(func):
        @wraps(func)  # 装饰器修复技术
        def inner(request, *args, **kwargs):
            ret = request.get_signed_cookie("is_login", default="0", salt="ban")
            if ret == "1":
                # 已经登录,继续执行
                return func(request, *args, **kwargs)
            # 没有登录过
            else:
                # ** 即使登录成功也只能跳转到home页面,现在通过在URL中加上next指定跳转的页面
                # 获取当前访问的URL
                next_url = request.path_info
                return redirect("/app01/login/?next={}".format(next_url))
        return inner
    
    
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            pwd = request.POST.get("pwd")
            next_url = request.GET.get("next")
    
            if username == "alex" and pwd == "dsb":
                # return redirect("/home/")
                # 服务器返回的响应对象
    
                # 通过URL中的next参数指定跳转的页面,如果为空,默认跳转到home页面
                if next_url:
                    rep = redirect(next_url)
                else:
                    print("ban")
                    rep = redirect("/app01/home/")
    
                # 1. 设置cookie
                # rep.set_cookie("is_login", "1")
    
                # 2. 设置加盐cookie,max_age是cookie的生存时间
                rep.set_signed_cookie("is_login", "1", salt="ban", max_age=100)
                return rep
    
        return render(request, "app01/login.html")
    
    
    def home(request):
        # 获取cookie并判断
        # if request.COOKIES.get("is_login", 0) == "1":
        # 获取加盐cookie并判断
        ret = request.get_signed_cookie("is_login", default="0", salt="ban")
        if ret == "1":
            return render(request, "app01/home.html")
        else:
            return redirect("/app01/login/")
    
    
    # 注销函数
    def logout(request):
        # 删除cookie,操作的是响应对象,最后需要返回
        rep = redirect("/app01/login/")
        rep.delete_cookie("is_login")
        return rep
    
    
    @check_login
    def index(request):
        return render(request, "app01/index.html")
    
    

    参考:https://www.cnblogs.com/liwenzhou/p/8343243.html
    GitHub地址:https://github.com/protea-ban/oldboy/tree/master/s9day71/xiawu

  • 相关阅读:
    分享jstl实现分页,类似百度分页
    分享git的常用命令
    ubuntu certbot 生成免费泛域名证书
    es创建普通索引以及各种查询
    动态代理
    开闭原则
    单一原则
    单例模式
    设计模式之观察者模式
    SpringBoot集成spring-data-jpa注入Bean失败
  • 原文地址:https://www.cnblogs.com/banshaohuan/p/9493021.html
Copyright © 2011-2022 走看看