cookies与session

cookies与session的关系

cookies

在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。

session

session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。

两者传输的关系

1.客户端第一请求,服务端会发送登陆页面过去

2.客户第二次请求并提交用户名和密码后,服务端会向客户端回写一个cookie值

3.如果我们设置了session,则会向客户端回写一个 {sessionid : 'lr3gmj3vpt0ytf7locqnb21p0cg63iek'},它会保存在客户端

4.服务端会将客户的隐私信息保存在了服务端的数据库中, 也就是session保存在了数据库中,默认放在django_session表中:{"dsjnalndjskanjdksa" : {"name":'jojo', 'age':12, 'addr':'dsabdsa'}},也就是以session值:用户信息的形式存储

5.我们可以理解为cookie的value值就是session的key,当我们再次向服务端发起请求时,服务端会通过sessionid来比对信息,然后返回用户信息

Cookie

#设置cookie
obj = redirect('/home/')
obj.set_cookie('username','hank666')

#删除cookie
#obj.delete_cookie('username')

#获取cookie
request.COOKIES.get('username')

实现cookie登录方式一

views.py

def login(request):
    if request.method =='POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'hank' and password == '123':
            #保存用户登录状态
            obj = redirect('/home/')
            #设置cookie
            obj.set_cookie('username','hank666')
            return obj
    return render(request,'login.html')

def home(request):
    # 校验浏览器是否有对应的cookie
    if request.COOKIES.get('username'):
        print(request.COOKIES)
        return HttpResponse('我是home页面,只有登录的用户才能访问')
    else:
        return redirect('/login/')

实现cookie登录方式二 (装饰器)

def login_auth(func):
    def inner(request,*args,**kwargs):
        #print('request.path_info:', request.path_info)  # 只拿路径部分 不拿参数
        #print('request.get_full_path():', request.get_full_path())  # 路径加参数

        # 执行被装饰函数之前为其装上新功能
        if request.COOKIES.get('username'):
            res = func(request,*args,**kwargs)
            return res
        else:
            return redirect('/login/')
    return inner

def login(request):
    if request.method =='POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'hank' and password == '123':
            #保存用户登录状态
            obj = redirect('/home/')
            #设置cookie
            obj.set_cookie('username','hank666')
            return obj
    return render(request,'login.html')

@login_auth
def home(request):
    # 校验浏览器是否有对应的cookie
    # if request.COOKIES.get('username'):
    #     print(request.COOKIES)
    #     return HttpResponse('我是home页面,只有登录的用户才能访问')
    # else:
    #     return redirect('/login/')
    return HttpResponse('我是home页面,只有登录的用户才能访问')

@login_auth
def index(request):
    return HttpResponse('我是index页面,只有登录的用户才能访问')

@login_auth
def demo(request):
    return HttpResponse('我是demo页面,只有登录的用户才能访问')

cookie登录方式二改进版 (装饰器)

def login_auth(func):
    def inner(request,*args,**kwargs):
        #print('request.path_info:', request.path_info)  # 只拿路径部分 不拿参数
        #print('request.get_full_path():', request.get_full_path())  # 路径加参数

        # 执行被装饰函数之前为其装上新功能
        target_url = request.path_info
        if request.COOKIES.get('username'):
            res = func(request,*args,**kwargs)
            return res
        else:
            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 == 'hank' and password == '123':
            # target_url = request.GET.get('next','/home/')
            target_url = request.GET.get('next')
            #判断用户登录之前是否有想要访问的url
            if target_url:
                obj = redirect(target_url)
            else:
                obj =redirect('/home/')
            #保存用户登录状态
            #设置cookie
            obj.set_cookie('username','hank666')
            return obj
    return render(request,'login.html')

@login_auth
def home(request):
    return HttpResponse('我是home页面,只有登录的用户才能访问')

@login_auth
def index(request):
    return HttpResponse('我是index页面,只有登录的用户才能访问')

@login_auth
def demo(request):
    return HttpResponse('我是demo页面,只有登录的用户才能访问')

@login_auth
def logout(request):
    obj = HttpResponse('注销了')
    obj.delete_cookie('username')
    return obj

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post">
    <p>username: <input type="text" name="username"></p>
    <p>password: <input type="text" name="password"></p>
    <input type="submit">
</form>    
</body>
</html>

注意:

session

Django设置session

request.session['key'] = value
    """
    1.django内部会自动生成一个随机字符串
    2.去django_session表中存储数据 键就是随机字符串 值是要保存的数据(中间件干的)
    3.将生成好的随机字符串返回给客户端浏览器   浏览器保存键值对
        sessionid  随机字符串
    """            

获取session

request.session.get('key')
        """
    1.django会自动取浏览器的cookie查找sessionid键值对 获取随机字符串
    2.拿着该随机字符串取django_session表中比对数据
    3.如果比对上了 就将随机字符串对应的数据获取出来并封装到request.session供用户调用
    """

删除当前会话的所有session数据

request.session.delete()

删除当前的会话数据并删除会话的Cookie(推荐使用)

request.session.flush()
    这用于确保前面的会话数据不可以再次被用户的浏览器访问
    例如,django.contrib.auth.logout() 函数中就会调用它。

注意:django中默认的session超时时间为14天

设置会话Session和Cookie的超时时间

request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略。

猜你喜欢

转载自www.cnblogs.com/baohanblog/p/12189335.html