cookie与session

cookie简介

大家都知道HTTP协议是无状态的。

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

一句有意思的话来描述就是人生只如初见,对服务器来说,每次的请求都是全新的。

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

Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。

cookie操作

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

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


obj1 = HttpResponse()
# 操作cookie
return obj1

obj2 = render()
# 操作cookie
return obj2

obj3 = redirect()
# 操作cookie
return obj3
# 如果你想要操作cookie,你就不得不利用obj对象


"""
设置cookie
    obj.set_cookie(key,value)
获取cookie
    request.COOKIES.get(key)
在设置cookie的时候可以添加一个超时时间
    obj.set_cookie('username', 'jack',max_age=3,expires=3)
    
    max_age
    expires
        两者都是设置超时时间的 并且都是以秒为单位
        需要注意的是 针对IE浏览器需要使用expires
主动删除cookie(注销功能)
obj.delete_cookie('key')

使用cookie实现简易的登录功能

# 装饰器
def log_auth(func):
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('username') == '123567':
            res = func(request, *args, **kwargs)
            return res
        else:
            last_addr = request.get_full_path()
            return redirect('/login/?last=%s' % last_addr)

    return inner

# 登录功能
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'xk' and password == '123':
            last_addr = request.GET.get('last')
            if last_addr:
                obj = redirect(last_addr)
            else:
                obj = redirect('/home/')
            obj.set_cookie('username', '123567')
            return obj
    return render(request, 'login.html')

# 首页
@log_auth
def home(request):
    return HttpResponse('Home')

# 注销
@log_auth
def logout(request):
    obj = redirect('/login/')
    obj.delete_cookie('username')
    return obj

# 其他功能
@log_auth
def index(request):
    return HttpResponse('index')
View Code

 

 

 

session简介

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session 对象的详细信息,请参阅“ASP应用程序”部分的“管理会话”。注意会话状态仅在支持cookie的浏览器中保留

session操作

# session数据是保存在服务端的,给客户端返回的是一个随机字符串
设置session request.session[
'key'] = value 获取session request.session.get('key') 设置过期时间

  django默认session的过期时间是14天
  但是你也可以人为的修改它

request.session.set_expiry()
    括号内可以放四种类型的参数
        1.整数                        多少秒
        2.日期对象               到指定日期就失效
        3.0                                一旦当前浏览器窗口关闭立刻失效
        4.不写                        失效时间就取决于django内部全局se    ssion默认的失效时间

清除session    
    request.session.delete()  # 只删服务端的 客户端的不删
    request.session.flush()  # 浏览器和服务端都清空(推荐使用)


session是保存在服务端的 但是session的保存位置可以有多种选择
    1.MySQL
    2.文件
    3.redis
    4.memcache
    ...

django_session表中的数据条数是取决于浏览器的
同一个计算机上(IP地址)同一个浏览器只会有一条数据生效
(当session过期的时候可能会出现多条数据对应一个浏览器,但是该现象不会持续很久,内部会自动识别过期的数据清除 你也可以通过代码清除)

主要是为了节省服务端数据库资源

 

session设置与取值内部详解

request.session['hobby'] = 'girl'
    """
    内部发送了那些事
        1.django内部会自动帮你生成一个随机字符串
        2.django内部自动将随机字符串和对应的数据存储到django_session表中
            2.1先在内存中产生操作数据的缓存
            2.2在响应结果django中间件的时候才真正的操作数据库
        3.将产生的随机字符串返回给客户端浏览器保存
    """
request.session.get('hobby')
    """
    内部发送了那些事
        1.自动从浏览器请求中获取sessionid对应的随机字符串
        2.拿着该随机字符串去django_session表中查找对应的数据
        3.
            如果比对上了 则将对应的数据取出并以字典的形式封装到request.session中
            如果比对不上 则request.session.get()返回的是None
    """
  

使用session完成一个简易的登录

def auth_log(func):
    def inner(request, *args, **kwargs):
        last_addr = request.get_full_path()
        if request.session.get('user'):

            res = func(request, *args, **kwargs)
            return res
        else:
            return redirect('/s_login/?last=%s' % last_addr)

    return inner


def s_login(request):
    if request.method == 'POST':
        user = request.POST.get('username')
        pwd = request.POST.get('password')
        if user == 'xk' and pwd == '123':
            request.session['user'] = user
            if request.GET.get('last'):
                return redirect(request.GET.get('last'))
            else:
                return redirect('/s_home/')
    return render(request, 's_login.html')


@auth_log
def s_home(request):
    return HttpResponse('首页页面,登录才能查看')


@auth_log
def index(request):
    current_user = request.session.get('user', None)
    
    return render(request, 'index.html', locals())


@auth_log
def del_log(request):
    request.session.flush()
    return redirect('/s_login/')
View Code

 

CBV如何添加装饰器

from django.views import View
from django.utils.decorators import method_decorator
"""
CBV中django不建议你直接给类的方法加装饰器
无论该装饰器能都正常给你 都不建议直接加
"""

# @method_decorator(login_auth,name='get')  # 方式2(可以添加多个针对不同的方法加不同的装饰器)
# @method_decorator(login_auth,name='post')
class MyLogin(View):
    @method_decorator(login_auth)  # 方式3:它会直接作用于当前类里面的所有的方法
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)
    # @method_decorator(login_auth)  # 方式1:指名道姓
    def get(self,request):
        return HttpResponse("get请求")

    def post(self,request):
        return HttpResponse('post请求')

 

posted @ 2022-03-08 20:05  椰子皮0oo0  阅读(52)  评论(0)    收藏  举报
1