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失效策略。