Cookie和Session

Cookie和Session

1.Cookie和Session介绍

  • 服务器保存在客户端浏览器上的信息都可以称之为cookie
  • 指代服务端让客户端保存的数据(存储在客户端上与用户信息相关的数据)
  • 它的表现形式一般都是k:v键值对(可以有多个)

1.2 Session

  • 保存在服务器上的信息都可以称之为session
  • 指代服务端保存的跟用户信息相关的数据
  • 它的表现形式一般都是 session_id :随机的字符串

2. Django操作Cookie

2.1 视图函数的返回值(三板斧)

  • 正常返回三板斧对象
return HttpResponse()
return render()
return redirect()
  • 变形
obj = HttpResponse()
return obj

obj1 = render()
return obj1

obj2 = redirect()
return obj2

如果想要操作cookie,必须进行以上变形才可以

2.2 设置cookie

# 1.获取响应对象
obj = HttpResponse("注册成功")
# 2.设置cookie
# max_age=5,设置超时时间 5s 到期
obj.set_cookie(key,value,max_age=5)
# 3.获取cookie
cookie = request.COOKIES.get('key')
# 4.删除注销cookie
obj.delete_cookie("key")
return obj

3.登陆功能实现

(1)简单实现

  • 路由
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('home/', views.home),
]
  • 视图
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == "dream" and password == "521":
            # 登陆成功之后,跳转到登陆成功之后才能看到的页面
            return redirect('/home/')
    return render(request, 'login.html')


def home(request):
    return HttpResponse("登陆成功!")
  • 前端
<form action="" method="post">
    <p>username:<input type="text" name="username" class="form-control"></p>
    <p>password:<input type="password" name="password" class="form-control"></p>
    <input type="submit" class="btn btn-success">
</form>
  • 问题
    • 登陆成功之后的跳转页面,不需要登陆也可以直接访问到,只需要给对应的地址即可

(2)解决登陆问题

from django.shortcuts import render, HttpResponse, redirect


# Create your views here.
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == "dream" and password == "521":
            # 登陆成功之后,保存用户登陆状态
            obj = redirect('/home/')
            # 让浏览器记录cookie
            obj.set_cookie("sign", "1314521")
            '''
            浏览器不单单只是帮我们保存cookie
            而且在后面每次访问的时候都会带着cookie
            '''
            # 登陆成功之后,跳转到登陆成功之后才能看到的页面
            return obj
    return render(request, 'login.html')


def home(request):
    # 读取携带的cookie,cookie正确登陆成功
    if request.COOKIES.get("sign") == "1314521":
        return HttpResponse("登陆成功!")
    # 读取携带的cookie,cookie不正确跳转到登陆页面
    return redirect('/login/')

(3)迭代-登陆认证装饰器

  • 用户如果没有登陆的情况下想访问一个需要登录的页面
  • 那么先跳转到登录页面,当用户输入正确的用户名和密码之后
  • 再跳转到用户之前想访问的页面去,而不是直接写死
from django.shortcuts import render, HttpResponse, redirect


# Create your views here.
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == "dream" and password == "521":
            # 获取用户上一次想要访问的url
            # 结果可能为空 -- 直接访问login
            tag_url = request.GET.get('tag_url')
            if tag_url:
                obj = redirect(tag_url)
            else:
                # 登陆成功之后,保存用户登陆状态
                obj = redirect('/home/')
            # 让浏览器记录cookie
            obj.set_cookie("sign", "1314521")
            '''
            浏览器不单单只是帮我们保存cookie
            而且在后面每次访问的时候都会带着cookie
            '''
            # 登陆成功之后,跳转到登陆成功之后才能看到的页面
            return obj
    return render(request, 'login.html')


# 校验用户登录状态的装饰器
def auth_check(func):
    def inner(request, *args, **kwargs):
        # 获取到用户上一次想要访问的url
        tag_url = request.get_full_path()
        # 读取携带的cookie,cookie正确登陆成功
        if request.COOKIES.get("sign") == "1314521":
            res = func(request, *args, **kwargs)
            return res
        else:
            # 读取携带的cookie,cookie不正确跳转到登陆页面
            return redirect(f'/login/?next={tag_url}')

    return inner


@auth_check
def home(request):
    return HttpResponse("home登陆成功!")


@auth_check
def index(request):
    return HttpResponse("index登陆成功!")


@auth_check
def func(request):
    return HttpResponse("func登陆成功!")

4.Django操作session

  • Django使用session的前提是已经迁移过数据库并且数据库中有 django_session 这张表
  • Django的session默认过期时间是 14 天
def login(request):
    if request.method == "POST":
        data = request.POST
        username = data.get("username")
        password = data.get("password")
        if username == "dream" and password == "521":
            # request.session["sign"] = "6666"
            # request.session["sign"] = "777"
            request.session["sign"] = "888"
            # 产生了一个随机的字符串
            # 把这个随机字符串跟加密的数据绑定在一起
            # 将这个随机字符串发送给客户端

            # 如果session中放入多个值的情况下
            # 默认采用最后一个session值而不是第一个

            # 设置过期时间
            # request.session.set_expiry(3)
            # 如果是数字的话,过期时间就是在指定 秒数后过期
            # request.session.set_expiry(0)
            # 如果参数是数字 0 ,过期时间是随着浏览器的关闭后,session 会直接过期
            #
            obj = HttpResponse("登陆成功")
            return obj
        return HttpResponse("登录失败")
    return render(request, "login.html", locals())


def index(request):
    sign = request.session.get("sign")
    if sign and sign == "888":
        return HttpResponse("index")
    return redirect("login")


def logout(request):
    print(request.session.get("sign"))
    # request.session.delete()
    # 该方法用于删除当前用户的Session数据,但会保留Session的Key。
    # 这意味着Session对象本身仍然存在,但其中的数据将被清空。
    # 下次访问时,如果Session没有被重新填充,则会得到一个空的Session对象。

    request.session.flush()
    # 该方法用于完全删除当前用户的Session,包括Session对象和所有相关数据。
    # 下次访问时,将创建一个新的空Session对象。
    print(request.session.get("sign"))
    return redirect("login")

5. 给CBV添加装饰器的三种方式

from django.views import View
from django.utils.decorators import method_decorator


def login(request):
    if request.method == "POST":
        data = request.POST
        username = data.get("username")
        password = data.get("password")
        next_url = request.GET.get("next_url")
        if username == "dream" and password == "521":
            if next_url:
                obj = redirect(next_url)
            else:
                obj = HttpResponse("登陆成功")
            obj.set_cookie("sign", "666")
            return obj
        return HttpResponse("登录失败")
    return render(request, "login.html", locals())


def home(request):
    # 获取cookie"
    sign = request.COOKIES.get("sign")
    if sign and sign == "666":
        return HttpResponse("这是正常的home页面")
    return redirect("login")


def login_auth(func):
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        sign = request.COOKIES.get("sign")
        if sign and sign == "666":
            obj = func(request, *args, **kwargs)
            return obj
        return redirect(f"/login/?next_url={next_url}")

    return inner


# CBV加装饰器方式二 : 在类上面加 @method_decorator(装饰器函数名,指定给哪个视图函数加装饰器)
# @method_decorator(login_auth, "get")
class Index(View):
    # CBV加装装饰器的方式三 : 直接重写父类的 dispatch方法,但是这种方法有弊端,弊端就是所有的视图函数都会收到影响
    @method_decorator(login_auth)
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

    # CBV 加装饰器方式一 : 直接在类视图上面 加 @method_decorator(装饰器函数名)
    # @method_decorator(login_auth)
    def get(self, request):
        return HttpResponse("这是正常的index页面")
posted @   Formerly0^0  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示