django Cookie与Session

django Cookie与Session

Cookie与Session简介

回忆:HTTP协议四大特征

1.基于请求响应

2.基于TCP的应用层协议

3.无状态:不保存客户端状态

4.无连接

最开始的网站都不需要用户注册 所有人来访问获取到的数据都是一样的

随着互联网的发展很多网站需要指定当前用户的状态

Cookie:保存在客户端与用户状态相关的信息

Session:保存在服务端与用户状态相关的信息

session的工作需要依赖于cookie

浏览器有资格拒绝保存服务端发送过来的cookie数据

早期客户端:

当你是一次输入用户名和密码时 浏览器(客户端)会有能力记住和保存起来你登入各个网站的用户名和密码 再次访问的时候浏览器帮你发送了你的用户名和密码

这种是直接保存在客户端安全性会非常的低 就比如当你去网吧上网登入微信 QQ假如电脑没有初始化重启 其他人来上网就能看到

随着互联网的发展很多网站需要指定当前用户的状态:

当你第一次输入用户名和密码之后 服务端会给你返回一个随机字符串

浏览器拿着个随机字符串 以后再访问这个服务端 把字符串给到服务端 服务端内部是用户信息对应好了的 哪个用户对应的哪个随机字符串 这样就能够知道你是谁 这样用户数据就保存在服务端了 而浏览器只保存了随机字符串 这样用户信息就在客户端查看不了

session的工作是得依赖cookie

将cookie记录清除 如图:

image

再登入 发现比未登入前多 而这些多出来的就是对身份的唯一标识

image

小知识拓展:

浏览器上是有拒绝保存cookie的 如果勾选上的话所有的登入页面功能都登入不上全部失效

image

因为所有的登入功能在输对用户名和密码之后都得在浏览器上保存一个随机字符串 而现在本地是没有保存随机字符串的功能了 那么服务端想给你发随机字符串却保存不了

这样每一次在登入请求时都得自己输用户名和密码 可却又去无法保存服务端发送过来的随机字符串 这样一来所有的登入功能都实现不了

总结:

cookie:保存在客户端与用户状态相关的信息

session:保存在服务端与用户状态相关的信息

session的工作需要依赖于cookie

django操作cookie

from django.shortcuts import render,HttpResponse,redirect
return render()
return HttpResponse()
return redirect()

要想操作cookie就不能直接返回HttpResponse对象 必须先用变量接收
obj1 = render()
return obj1
obj2 = HttpResponse()
return obj2
obj3 = redirect()
return obj3
def index_func(request):
    if request.method == 'POST':
        res = HttpResponse('登录成功')
        res.set_cookie('user_name', request.POST.get('username'))  # 键值对不能有中文
        res.set_cookie('pwd', request.POST.get('pwd'))  # 键值对不能有中文
        print(request.COOKIES.get('user_name'))
        return res
    return render(request, 'indexPage.html', locals())

image

登录成功后可以查看的视图函数

def home_func(request):

    if request.COOKIES.get('user_name') == 'ikun':
        return HttpResponse('登录用户')
    return redirect('/index/')

只有用户登入之后才可以随意访问home,这样浏览器就保存了cookie信息为键是name、值是当前登入的用户名

image

需求用户登录之后访问的页面有好几个

如果有很多视图,每个视图都加一个校验用户登录,那就很麻烦了

那么针对频繁操作我们可以写一个装饰器在不修改被装饰对象的源代码及调用方式,进行功能的添加。

装饰器

def login_auth(func):
    def inner(request,*args,**kwargs):
        # print(args,kwargs)
        if request.COOKIES.get('user_name') == 'ikun':
            return HttpResponse('登录用户')
        return redirect('/index/')
    return inner


@login_auth
def home_func(request):

    return HttpResponse('登录用户')

进阶操作:

用户没有登录之前想访问某个网站输入用户名密码之后就应该立马跳转回去

# print(request.path)  # 只获取用户输入的路由信息
# print(request.path_info)  # 只获取用户输入的路由信息
# print(request.get_full_path())  # 获取用户输入的路由信息+问号后面携带的数据

前两个都是获取用户输入的路由信息 第三个是获取用户输入的路由的信息+问号后面携带的数据

def login_auth(func):
    def inner(request, *args, **kwargs):
        # print(args,kwargs)
        if request.COOKIES.get('user_name') == 'ikun':
            return func(request, *args, **kwargs)
        print(request.path)
        return redirect('/index/' + '?next=' + request.path)

    return inner

def index_func(request):
    if request.method == 'POST':
        res = HttpResponse('登录成功')

        if request.GET.get('next'):
            res = redirect(request.GET.get('next'))

        res.set_cookie('user_name', request.POST.get('username'))  # 键值对不能有中文
        res.set_cookie('pwd', request.POST.get('pwd'))  # 键值对不能有中文
        # print(request.COOKIES.get('user_name'))
        print(request.GET.get('next'))

        return res
    return render(request, 'indexPage.html', locals())

@login_auth
def home_func(request):

    return HttpResponse('登录用户')

未登录的

image

登录成功直接跳转

image

总结:

装饰器是把用户登入成功之后的视图函数都装上了

那么用户在没有登入的情况下 就能够拿到用户想要访问的那个路由 但是必须得要先登入

因为只有在执行完登入功能之后才能正真的跳转到一个页面去

那么在跳转到登入功能之前把用户正真想访问的路由塞给登入的这个路由里

这样在登入完之后就可以在request.GET.get拿到用户在登入之前想访问的地址

django操作session

由于session是保存在服务端上面的数据 就应该有个地方能够存

我们只需要执行数据库迁移命令即可 django会自动创建很多需要的表

django默认的session失效时间是14天

设置session

request.session['key'] = values

1.生成一个随机字符串

2.对value数据做加密处理 并在django_session表中存储 随机字符串>>>加密数据

3.将随机字符串也发送一份给客户端保存(cookie)session:随机字符串

获取session

request.session.get('key')

1.自动获取随机字符串

2.去django_session表中根据随机字符串获取加密的数据

3.自动解密数据并处理到request.session.get()中

补充说明

1.可以设置过期时间

2.存储session数据的位置也可以修改

补充知识
	 # 将所有Session失效日期小于当前日期的数据删除
    request.session.clear_expired()
    # 检查会话session的key在数据库中是否存在
    request.session.exists("session_key")
    # 删除当前会话的所有Session数据
    request.session.delete()
    # 删除当前的会话数据并删除会话的Cookie。
    request.session.flush() 
    # 设置会话Session和Cookie的超时时间
    request.session.set_expiry(value)
        * 如果value是个整数,session会在些秒数后失效。
        * 如果value是个datatime或timedelta,session就会在这个时间后失效。
        * 如果value是0,用户关闭浏览器session就会失效。
        * 如果value是None,session会依赖全局session失效策略。

设置session数据

def session_func(request):
    session_value = 'session——张三'
    request.session['username'] = session_value
    return HttpResponse(session_value)

image

获取session数据

def get_session(request):
    username = request.session.get('username')

    return HttpResponse(username)

image

底层原理

自定获取到随机字符串 去django表中获取随机字符串加密的数据在自动解密处理到request.session.get(key)中

设置过期时间

单位是秒

def session_func(request):
    session_value = 'session——张三'
    request.session['username'] = session_value
    request.session.set_expiry(5)
    return HttpResponse(session_value)

过期后在拿就拿不到数据了

image

储存session数据的位置可以修改

可以规定存在表里还是文件里或者缓存数据库里都可以

posted @ 2022-12-26 21:01  clever-cat  阅读(27)  评论(0编辑  收藏  举报