doina

一个小菜鸟运维工程师.

django cookie学习

[toc]

cooki介绍

Cookie 定义

“Cookie”是小量信息,由网络服务器发送出来以存储在网络浏览器上,从而下次这位独一无二的访客又回到该网络服务器时,可从该浏览器读回此信息。这是很有用的,让浏览器记住这位访客的特定信息,如上次访问的位置、花费的时间或用户首选项(如样式表)。Cookie 是个存储在浏览器目录的文本文件,当浏览器运行时,存储在 RAM 中。一旦你从该网站或网络服务器退出,Cookie 也可存储在计算机的硬驱上。当访客结束其浏览器对话时,即终止的所有 Cookie。

为什么要使用Cookie?

首先我们要知道一个概念,web程序是使用HTTP协议传输的,而HTTP协议是无状态的协议,对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

设置和读取cookie

  • 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获取(不是绝对,底层抓包可以获取到也可以被覆盖)
def cookie(request):
    # 读取cookie
    request.COOKIES['username111']
    request.COOKIES.get('username111')



    # 设置cookie时必须对对象设置, 吧rander赋值给一个对象, 然后进行操作
    response = render(request,'index.html')

    # 设置cookie,关闭浏览器失效
    response.set_cookie('key',"value")

    # 设置cookie, N秒只有失效
    response.set_cookie('username111',"value",max_age=10)

    # 设置cookie, 截止时间失效
    import datetime
    current_date = datetime.datetime.utcnow()
    current_date = current_date + datetime.timedelta(seconds=5)
    response.set_cookie('username111',"value",expires=current_date)
    response.set_cookie('username111',"value",max_age=10)

    # request.COOKIES.get('...')
    # response.set_cookie(...)
    obj = HttpResponse('s')

    obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf")
    request.get_signed_cookie('username',salt="asdfasdf")

    return response

使用cookie实现登录跳转

view.py

# 模拟用户列表
users = {
    'baiyongjie': {'password': '123456'},
    'byj': {'password': '123456'}
}

# 定义登录函数
def login(request):
    if request.method == "GET":
        return render(request, 'login.html')

    elif request.method == "POST":
        user = request.POST.get("username")
        pwd = request.POST.get("password")
        u_dic = users.get(user)

        if not u_dic:
            return render(request, 'login.html')

        if u_dic['password'] == pwd:
            res = redirect('/home')
            res.set_cookie('user', user)
            return res
        else:
            print('password is error..')
            return render(request, 'login.html')


# 定义登录后函数
def home(request):
    if request.method == "GET":

        user = request.COOKIES.get('user')
        if user:
            return render(request, 'home.html', {'username': user})
        else:
            return render(request, 'login.html')

url.py

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('login/', views.login),
    path('home/', views.home)
]

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
<form action="/login/" method="POST">
    <input type="text" name="username" placeholder="用户名">
    <input type="password" name="password" placeholder="密码">
    <input type="submit" value="登录">
</form>
</body>
</html>

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>home</title>
</head>
<body>
<h1>
    欢迎回来 {{ username }}
</h1>
<h2>
    再次欢迎 <span id="two"></span>
</h2>
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
    // 页面加载完执行函数, 打印日志到浏览器控制台, 然后修改span标签内的值
    $(function () {
        var v = $.cookie('user');
        console.log(v)
        $("#two").text(v)
    });
</script>
</body>
</html>

使用cookie配合装饰器进行用户验证

FBV(Function)

url.py

urlpatterns = [
    path('login/', views.login),
    path('home/', views.home),
]

在utils目录中见一个permission的py文件

from django.shortcuts import redirect

def auth(func):
    def inner(request, *args, **kwargs):
        # 获取user的cookie
        user = request.COOKIES.get('user')
        # 如果不存在, 则返回登录页
        if not user:
            return redirect('/login/')
        # 否则就执行使用此装饰器的函数
        return func(request, *args, **kwargs)
    return inner

在view中使用装饰器

from utils.permission import auth


users = {
    'baiyongjie': {'password': '123456'},
    'byj': {'password': '123456'}
}

def login(request):
    # 如果请求方式是GET, 就返回login.html页面
    if request.method == "GET":
        return render(request, 'login.html')

    # 如果请求方式是POST, 获取用户名和密码进行验证
    elif request.method == "POST":
        user = request.POST.get("username")
        pwd = request.POST.get("password")

        # 如果用户名不存在, 则返回登录界面
        u_dic = users.get(user)
        if not u_dic:
            return render(request, 'login.html')

        # 如果用户名存在, 则验证密码, 如果密码正确, 这跳转到首页(这里用home代替首页), 并定义一个username的cookie返回给浏览器
        if u_dic['password'] == pwd:
            res = redirect('/home/')
            res.set_cookie('user', user, max_age=5)
            return res

        # 如果用户名存在, 密码错误, 则输出密码错误, 跳转到登录界面
        else:
            print('password is error..')
            return render(request, 'login.html')

@auth
def home(request):
    # 如果登录方式为GET, 切通过auth装饰器验证, 那么设置dady的变量, 并返回home.html页面
    if request.method == "GET":
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})

CBV (Class )

url.py

urlpatterns = [
    path('order/', views.order.as_view())
]

在utils目录中见一个permission的py文件

from django.shortcuts import redirect

def auth(func):
    def inner(request, *args, **kwargs):
        # 获取user的cookie
        user = request.COOKIES.get('user')
        # 如果不存在, 则返回登录页
        if not user:
            return redirect('/login/')
        # 否则就执行使用此装饰器的函数
        return func(request, *args, **kwargs)
    return inner

在view中使用装饰器 – 第一种

from utils.permission import auth
from django.utils.decorators import method_decorator

class order(views.View):

    # 使用django中的method_decorator装饰器来套用我们的auth装饰器, 如果有多重方法, 需要在所有方法上面都使用@method_decorator(auth)来进行验证
    @method_decorator(auth)
    def get(self, request):
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})

    # 使用@method_decorator(auth)来进行验证
    @method_decorator(auth)
    def post(self, request):
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})

在view中使用装饰器 – 第二种

from utils.permission import auth
from django.utils.decorators import method_decorator

class order(views.View):

    # 所有的请求都先通过dispatch方法, 然后在执行下面的方法, 但是需要多定义一个方法
    @method_decorator(auth)
    def dispatch(self, request, *args, **kwargs):
        return super(order, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})

    def post(self, request):
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})

在view中使用装饰器 – 第三种

# 表示对类中的dispatch方法进行装饰, 不需要再写, 直接从父类中继承
@method_decorator(auth, name='dispatch')
class order(views.View):

    def get(self, request):
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})

    def post(self, request):
        dady = 'baiyongjie'
        return render(request, 'home.html', {'username': dady})
点赞

发表评论

邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据