Django-Cookie和session组件

一、cookie session token

cookie:客户端浏览器上的键值对
session:存在服务端的键值对
token:加密的键值对,如果放在客户端浏览器上,它就叫cookie,它是服务端签发的加密字符串

详细解读可看:https://www.cnblogs.com/liuqingzheng/articles/8990027.htmlp

二、django中cookie的使用

cookie是在客户端上的键值对,那么不论我们是向客户端拿cookie还是发cookie其实都是类似字典。我们这里的客户端一般来说是说浏览器。
如果使用的是JsonResponse,使用ajax发出的请求和浏览器发出的请求是不同的,浏览器发出的请求是自带cookie的,而js代码是不会自带cookie的,所以我们需要自己操作cookie存到ajax中,自己写进去

ookie规范
	-记住:当前网站在浏览器上cookie个数和大小有限制,(不同浏览器可能不同,但是肯定有上限)
 	-Cookie大小上限为4KB;
 	-一个服务器最多在客户端浏览器上保存20个Cookie;
 	-一个浏览器最多保存300个Cookie;

1.发送cookie(新增,修改)

向客户端发送cookie

新增和修改是一样的方法,因为是字典的使用方法,同一个键使用不同的值就是修改,添加新的键就是新增

def cookie_test(request):
    # 浏览器向后台发一个请求,就在浏览器写入cookies,name = yang
    obj=HttpResponse('ok')
    obj.set_cookie('name','yang')  # 写入到浏览器了,在http响应头里:cookie: name=lqz
    return obj

2.获取cookie(查)

获取客户端请求的cookie

# 获取客户端传来的cookie
def get_cookie(request):

    print(request.COOKIES)
    print(request.COOKIES.get('name'))
    return HttpResponse('获取ok')

3.删除cookie(删除)

删除客户端的cookie

# 删除客户端的cookie,此处的删除,是把客户端,name这个键对应的值给删除了,使其值为空。本质是让这个cookie过期。
def delete_cookie(request):
    obj=HttpResponse('删除ok')
    obj.delete_cookie('name')
    return obj

4.带签名的cookie(加盐,加密)

增,改:obj.set_signed_cookie('name','yang','123')
删: obj.delete_cookie('name')  # 设置过期
查: request.get_signed_cookie('name',salt='123')

5.cookie方法的参数

设置过期时间是为了防爬虫而不是为了让用户免登录,防止爬虫拿到session后能永久使用。

def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
               domain=None, secure=False, httponly=False)

# key
# value
# max_age:超时时间,传个数字,以秒计,过期时间,有默认值 (5天后过期:60*60*24*5)
以下了解:
# expires:超时时间,传时间对象,date=datetime.timedelta()
# path:默认 / 表示当前域下的所有路径
# domain:在那个域下有效
# secure:是否Https传输cookie
# httponly:cookie只支持http传输

三、django中session的使用

session是存在于服务端的键值对。单单从使用来说,和cookie没什么区别

在django中使用session,默认把session存在数据库中。所以我们要先迁移数据库。如果不迁移,会报错。

session只有第一次会生成随机字符串,后面新加的session只是把数据加进去或者修改然后加密,再存进去。但是随机字符串是不变的。

即一个浏览器只有一个session。所以不允许一个浏览器登录多个账号,多个浏览器支持登录一个用户。这里的一个浏览器,是指同一个服务器,比如淘宝给浏览器只会给一个,但是登录京东,京东也可以给一个。

个人测试:
当在一个浏览器登录第二个用户时,随机字符串不变,但是发现在数据库中加密的数据改变了,正是上面所说的,不能一个浏览器登录多个用户。

1.session使用

# 必须先创建了数据库并迁移数据即(makemigrations,migrate)
增.改:request.session['name']='yang'
查:request.session['name']
删:del request.session['name']
设置过期时间:request.session.set_expiry(10)
你可以传递四种不同的值给它:
* 如果value是个整数,session会在些秒数后失效(适用于整个Django框架,即这个数值时效时整个页面都会
session失效)。 
* 如果value是个datatime或timedelta,session就会在这个时间后失效。 
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。

2.session的其他使用

request.session.setdefault('k1', 123) # 给字典设默认值
request.session.get('name', None)  # 设该键设默认值
del request.session['k1']  # 删除该键的session
# 三种正常的字典取值
request.session.keys()
request.session.values()
request.session.items()

request.session.session_key  # 获取那个随机字符串,django_session表中session_key字段
request.session.clear_expired()  # 清除过期的session
request.session.exists("session_key")  # 判断这个随机字符串(session_key字段),有没有数据
request.session.delete()  # 删除所有的值,django_session表中删除当前登录者的这条记录
request.session.flush()  # 干了上面那个事,把cookie设置为过期

3.session的配置

1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'     # 引擎(默认)

2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 

4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

其他公用设置项:
SESSION_COOKIE_AGE = 1209600   # Session的cookie失效日期(2周)(默认)***以上记住

以下了解:
SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
SESSION_COOKIE_NAME = "sessionid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False  # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输(默认)
SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session,默认修改之后才保存(默认)

4.session深入解读

从django的请求生命周期可知,一个http请求进入我们的服务器要先经过中间件。

image-20200924175613811

1.设置session
我们要设置session,是从视图函数开始的,比如
request.session['name'] = 'yang',当响应出去的时候,
会先经过session的中间件,此时中间件帮助我们生产随机字符串
并且把session字典中的数据存到我们的数据库中,然后把session
作为key随机字符串作为value存到cookie中。
2.读取session
当请求进来时,依然是先经过中间件。此时中间件帮助我们去数据库查
数据,他是拿着随机字符串去数据库查,然后把获取的data数据解密
放到request.session中。所以到了视图函数中我们可以直接从这里
面拿到session
3.修改session
当我们在视图函数中对进来的数据进行处理后,如果改了session的
值,那么当响应出去的时候,会把数据部分替换然后再加密存入数据
库。

django的session原理

中间件怎么判断你修改了session然后去数据库修改value值?
是利用了重写字典的setitem魔术方法,里面加一个标志,modify原来为False,一旦调用了session.[key] = value,就会触发这个魔术方法,一旦触发了魔术方法直接把modify设置为True,那么中间件就重新加密数据存到数据库。

原文地址:https://www.cnblogs.com/chiyun/p/14066800.html