首页 > 技术文章 > cookie和session

zfb123- 2019-10-30 21:05 原文

cookie和session

由于HTTP协议是无状态的,无法记录,也就是说每次访问都会把访问者当成一个新的对象,那浏览器来说,如果浏览器关闭cookie,所有需要登录的功能都不能用。

浏览器关闭方式:

打开浏览器设置》高级设置》》网站设置》cookie关闭

查看方式:

打开浏览器》F12》选择Application》

​ cookie是保存在客户端浏览器上的键值对

​ 是服务端设置在客户啊短浏览器上的键值对也就意味着浏览器其实是可以拒绝服务端命令的,默认情况下浏览器都是直接让服务器设置键值对

​ Django三板斧:

				return  HTTPResponse()

​				return  render()

​				return  redirect()

​				变形:

​					obj1 = HTTPResponse()

​					return  obj1

​					obj2 = render()

​					return obj2
​					obj3 = redirect()
​					return obj3

设置cookie

obj.set_cookie()

rep = HttpResponse(...)
rep = render (request, ...)
rep.set_ cookie(key,value,...)
rep.set_ signed cookie (key,value,3a1t='加密盐',max age=None, ....

参数:
●key,键
●value=",值
max_ age= None,超时时间
●expires=None, 超时时间(IE requires expires, so set it if hasn't been already,)
●path=/" Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
●domain=None, Cookie生效的域名
●secure=False, https传输
●httponly=False 只能http协议传输,无法被JavaScript获取 (不是绝对,底层抓包可以获取到也可以被覆盖)

获取

request.COOKIES.get()

request.COOKIES['key']
request.get_signed_cookie{key,default=RAISE_ERROR, salt='', max_age=None}

​ 参数:

  • default:默认值
  • salt: 加密盐
  • max_age:后台控制过期时间

删除

​ obj.delete_cookie

def logout(request):
  rep = redirect("/login/")
  rep.delete_cookie("/user/") # 删除用户浏览器上之前设置的usercookie值
  return rep

session

session是保存在服务器上的键值对

django session默认的过期时间是14天

session
session是保存在服务器上的键值对

django session默认的过期时间是14天

操作session

设置session
request.session['key'] = value # 仅仅只会在内存产生一个缓存
"""
1.django内部自动生成了随机的字符串
2.在django_session表中存入数据
session_key session_data date
随机字符串1 数据1 ...
随机字符串2 数据2 ...
随机字符串3 数据3 ...
3.将产生的随机字符串发送给浏览器 让浏览器保存到cookie中
sessionid:随机字符串

"""
获取session
request.session.get('key')
"""
1.浏览器发送cookie到django后端之后 django会自动获取到cookie值
2.拿着随机字符串去django_session表中比对 是否有对应的数据
3.如果比对上了 就讲随机字符串所对应的数据 取出赋值给request.session
如果对不上 那么request.session就是个空

"""

django session表是针对浏览器的
不同的浏览器来 才会有不同的记录

删除session
request.session.delete() # 只删除服务端的session

request.session.flush() # 浏览器和服务端全部删除

session也可以设置超时时间
request.session.set_expiry(value多种配置)

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

总结:总结而言: Cookie弥补了HTTP无状态的不足,让服务器知道来的人是”谁”;但是Cookiel以文本的形式保存在本地,自身安全性较差;所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。另外,上述所说的Cookie和Session其实是共通性的东西, 不限于语言和框架。

代码实现以上功能:

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^home/', views.home),
    url(r'^index/', views.index),
    url(r'^logout/', views.logout),
    url(r'^set_session/', views.set_session),
    url(r'^get_session/', views.get_session),
    url(r'^delete_session/', views.delete_session),
]

settings.py

注释'django.middleware.csrf.CsrfViewMiddleware',
配置: STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

views.py

from django.shortcuts import render, HttpResponse, redirect

# Create your views here.


def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'zhang' and password == '123':
            old_path = request.GET.get('next')
            if old_path:
              	# 保存用户登录状态
                obj = redirect(old_path)
            else:
                obj = redirect('/home/')
            obj.set_cookie('name', 'zhang') # 让客户端浏览器 记录一个键值对
            return obj
    return render(request, 'login.html')


from functools import wraps


def login_auth(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('name'):
            res = func(request, *args, **kwargs)
            return res
        else:
            target_url = request.path_info
            return  request('/login/?next=%s'%target_url)
    return inner


@login_auth
def home(request):
    return HttpResponse('请先登录')


@login_auth
def index(request):
    return HttpResponse('index也需要先登录')


@login_auth
def logout(request):
    obj = redirect('/login/')
    obj.delete_cookie('name')
    return obj


def set_session(request):
    request.session['username'] = 'li'
    request.session.set_expiry(value=0)
    request.session['password'] = '123'
    return HttpResponse("设置session")


def get_session(request):
    print(request.session.get('username'))
    print(request.session.get('password'))
    return HttpResponse('获取session')


def delete_session(request):
    request.session.flush()
    return HttpResponse("删除session")

tests.py

from django.test import TestCase

# Create your tests here.
from functools import wraps
def login_auth(func):
    @wraps(func)
    def inner(*args,**kwargs):
        """我是inner函数"""
        res = func(*args,**kwargs)
        return res
    return inner

@login_auth  # login(变量名) = login_auth(真正的login函数内存地址)
def login():
    """
    我是login函数
    :return:
    """
    ...
print(login)
print(help(login))

前端文件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.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.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>

推荐阅读