cookie与session(全面了解)

一:cookie与session

1.什么是Cookie?
HTTP cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一个服务器再发起请求时被携带并发送到服务器上,通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登陆状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

Django中的cookie和session

2.Cookie主要用于以下三个方面
  • 会话状态管理(如用户登陆状态,购物车,游戏分数或其他需要记录的信息)
  • 个性化设置(如用户自定义设置,主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)
3.什么是Session?
Session代表着服务器和客户端一次会话的过程。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者超时Session超时失效时会话结束。

image

4.Cookie与Session有什么不同?
  • 作用范围不同,Cookie保存在客户端(浏览器),Session保存在服务器端。

  • 存取方式的不同,Cookie只能保存ASCII,Session可以存任意数据类型,一般情况下我们可以在Session中保持一些常用变量信息,比如说Userid等。

  • 有效期不同,Cookie可设置为长时间保持,比如我们经常使用的默认登陆功能,Session一般失效时间较短,客户端关闭或者Session超时都会失效

  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。

  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

  • session是基于cookie工作的(其实大部分的保存用户状态的操作都需要使用到cookie)

5.为什么需要Cookie和Session,他们有什么关联?
1.说起来为什么需要 Cookie ,这就需要从浏览器开始说起,我们都知道浏览器是没有状态的(HTTP 协议无状态),这意味着浏览器并不知道是张三还是李四在和服务端打交道。这个时候就需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,那这套机制的实现就需要 Cookie 和 Session 的配合。

看完这篇Session、Cookie、Token,和面试官扯皮就没问题了- 程序员cxuan - 博客园

1.用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。

2.当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

3.根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。
7.应用场景(以登陆功能为例)
7.1不完善(影响用户体验)
1.以登录功能为例:如果不保存用户登陆状态,也就意味着用户每次访问网站都需要重复的输入用户名和密码(你觉得这样的网站你还想要吗?)
7.2完善(提示用户体验)
2.当用户第一次登陆成功之后,将用户的用户名和密码返回给用户浏览器,让用户浏览器保存在本地,之后访问网站的时候浏览器自动将保存在浏览器上的用户名和密码发送给服务端,服务端获取之后自动验证
8.简述工作原理
1.当用户登陆成功之后,服务端产生一个随机字符串(在服务端保存数据,用k:v键值对的形式),交由客户端浏览器保存。
2.之后客户端在访问服务端的时候,都带着该随机字符串,服务端去数据库中比对是否有对应的随机字符串从而获取到对应的用户信息

隐患:
如果你拿到了截获到了该随机字符串,那么你就可以冒充当前用户 其实还是有安全隐患的

解决隐患:
你要知道在web领域没有绝对的安全也没有绝对的不安全,只能不断的优化,加强。
9.token
session虽然数据是保存在服务端的 但是禁不住数据量大
服务端不再保存数据
	1.登陆成功之后 将一段用户的数据进行加密(加密算法之后你公司开发知道)
	2.将加密之后的结果拼接在信息后面 整体返回浏览器保存
	3.浏览器下次访问的时候带着该信息 服务端自动切去前面一段信息再次使用自己的加密算法跟浏览器尾部的密文进行比对
10.jwt认证
  • 三段信息 后期更新

二:Cookie操作

1.虽然Cookie是服务端告诉客户端浏览器需要保存内容
2.但是客户端浏览器可以选择拒绝保存,如果禁止了,那么只要需要记录用户状态的网站登陆功能都无法使用了!

image

# 视图函数的返回值
return HttpResponse()
return render()
return redirect()

三:操作Cookie格式

1.如果你想要操作cookie,你就不得不利用obj对象
2.在中间利用对象操作Cookie

obj1 = HttpResponse()
# 操作cookie
return obj1

obj2 = render()
# 操作cookie
return obj2

obj3 = redirect()
# 操作cookie
return obj3

四:使用Cookie方法

设置cookie
obj.set_cookie(key,value)  # k:v键值对形式

获取cookie
request.COOKIES.get(key)  # 当作字典看 通过键拿值
    
在设置cookie的时候可以添加一个超时时间
obj.set_cookie('username', 'jason666',max_age=3,expires=3)

注销功能 主动删除cookie
obj.delete_cookie('username/键')

五:解析Cookie设置超时时间两者方法区别:

max_age
expires

1.两者都是设置超时时间的 并且都是以秒为单位
2.需要注意的是 针对IE浏览器需要使用expires

六:Cookie项目需求

1.我们完成一个真正的登陆功能
2.校验用户是否登陆的装饰器
1.目前缺点 装饰器
1.用户如果在没有登陆的情况下想访问一个需要登陆的页面
2.那么先跳到登陆页面 用户输入正确的用户名和密码之后
3.应该跳转到用户之前想要访问的页面去 而不是直接写死
2.解决方法
1.在装饰器login_auth内设置一个获取用户上一次想访问的url
2.将用户想访问的url放在当作参数get请求重定向发送给login
3.login获取用户想访问的url,然后判断生成对象,重定向返回!
3.实现Cookie项目
from django.shortcuts import render, HttpResponse,redirect

# 校验用户是否登陆的装饰器
def login_auth(func):
    def inner(request, *args, **kwargs):
        # print(request.path_info)
        # print(request.get_full_path())  # 两种方法能够获取到用户上一次想要访问的url
        # 获取用户上一次想访问的url
        target_url = request.get_full_path()
        # 获取cookie
        if request.COOKIES.get('username'):
            return func(request, *args, **kwargs)
        else:
            # 在用户没有登陆的情况 携带用户想访问的url参数
            return redirect('/login/?next=%s' % target_url)
    return inner


# 登陆功能
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'jason' and password == '123':
            # 获取用户上一次想要访问的url
            target_url = request.GET.get('next')  # 这个结果可能是None
            if target_url:
                # 保存用户登陆状态
                obj = redirect(target_url)
            else:
                # 保存用户登陆状态
                obj = redirect('/home/')

            # 2.让浏览器记录cookie数据 设置cookie
            obj.set_cookie('username','jason666')  # 告诉浏览器存一个k:v键值对
            """
            1.浏览器不单单会帮你存
            2.而且后面每次访问你的时候还会带着它过来
            """
            # 跳转到一个需要用户登陆之后才能看的页面
            return obj
    return render(request, 'login.html')



@login_auth
def home(request):
    # # 1.获取cookie信息 判断有没有登陆
    # if request.COOKIES.get('username') == 'jason666':
    #     return HttpResponse('home主页,登陆成功之后才能进入')
    # # 2.没有登陆应该跳转到登陆页面
    # return redirect('/login/')

    # 装饰器代表以上nobility方式

    return HttpResponse('home主页,登陆成功之后才能进入')



@login_auth
def index(request):
    return HttpResponse('index页面,登陆成功之后才能进入')



@login_auth
def func(request):
    return HttpResponse('func页面,登陆成功之后才能进入')

image

4.设置超时时间
# 2.让浏览器记录cookie数据 
obj.set_cookie('username','jason666', max_age=5)  # 告诉浏览器存一个k:v键值对

max_age=5 		: 设置超时时间 到时候自动清除cookie

image

5.注销功能
# 只有登陆的用户才能注销
@login_auth
def logout(request):
    # 返回主页
    obj = redirect('/login/')
    # 删除指定的键值对
    obj.delete_cookie('username')
    return obj
6.注销作用:
注销之后,就已经清除Cookie,就不能再访问home了

image

七:session操作

session数据是保存在服务端的(存?),给客户端返回的是一个随机字符串

sessionid	: 随机字符串
1.在默认情况下操作session的时候需要django默认的一张django_session表
2.列如数据库迁移:
当我们执行数据库迁移命令
django会自己创建很多表 django_session就是其中的一张

image

3.django默认session过期时间
django默认的session的过期时间是14天
但是你也可以人为的修改它
4.session操作格式
设置session
request.session['key'] = value

获取session
request.session.get('key')

八:实际操作设置与获取session

1.设置session
def set_session(request):
    request.session['hobby'] = 'girl'
    return HttpResponse('嘿嘿嘿')

image

2.获取session
def get_session(request):
    print(request.session.get('hobby'))
    return HttpResponse('获取了')

image

3.设置session内部工作原理
1.django内部会自动帮你生成一个随机字符串
2.django内部自动将随机字符串和对应的数据存储到django_session表中
	中间件第二个执行:
	2.1 先在内存中产生操作数据的缓存
	2.2 在响应经过django中间件的时候才真正的操作数据库
3.将产生的随机字符串返回给客户端浏览器保存
4.获取session内部工作原理
1.自动从浏览器请求中获取session对应的随机字符串
2.拿着该随机字符串去django_session表中查找对应的数据
3.如果比对上了 则将对应的数据取出并以字典的形式封装到request.session中
4.如果比对不上 则request.session.get()返回是None
5.django_session表中的数据条数是取决于浏览器的
1.django_session表中的数据条数是取决于浏览器的
2.同一个计算机上(IP地址)同一个浏览器只会有一条数据生效,不同的浏览器才会产生每条数据
3.(当session过期的时候可能会出现多条数据对应一个浏览器,但是该现象不会持续很久,内部会自动识别过期的数据清除 你也可以通过代码清除)

原因:
	主要是为了节省服务端数据库资源,不然同一个浏览器一直访问,每次访问会产生一条数据的话,会极大的影响数据库资源与内存消耗。

image

6.设置过期时间
request.session.set_expiry()

括号内可以放四种类型的参数:

1.整数						 多少秒
2.日期对象			   			到指定日期就失效
3.0							   一旦当前浏览器窗口关闭立刻失效
4.不写						 失效时间就取决于django内部全局session默认的失效时间
7.设置过去时间实际使用
设置session
def set_session(request):
    # 设置session
    request.session['hobby'] = 'girl'
    # 设置过期时间
    request.session.set_expiry(3)
    return HttpResponse('设置了')


# 获取session
def get_session(request):
    # 判断session
    if request.session.get('hobby'):
        print(request.session)
        print(request.session.get('hobby'))
        return HttpResponse('获取了')
    return HttpResponse('失效,未获取')

image

8.清除session
request.session.delete()  # 只删服务端的 客户端的不删
request.session.flush()  # 浏览器和服务端都清空(推荐使用)
9.使用清除session
# 删除session
def del_session(request):
    request.session.delete()
    return HttpResponse('删除')

image

10.session是保存在服务端的 但是session的保存位置可以有多种选择
1.MySQL
2.文件
3.redis
4.memcache
posted @ 2022-03-15 14:42  AlexEvans  阅读(466)  评论(0编辑  收藏  举报