django中session的源码解析以及使用
在大部分网站中,都需要用到用户id以及登陆状态,这时候就需要用到session。
说一说session概念:
Session是存在server端,当client向server发起request的时候,会产生一个session,用来存放client的一些信息,比如id等,当然这些信息是我们可以自己设置需要存什么。每个client有一个唯一的sessionid,所以对于不同client,他们用自己的sessionid拿到的信息都是自己的。
说到这里,有一个非常经典的面试题:
请说一说session和cookie的区别?具体答案我就不在这里介绍了。不知道的朋友们可以在网上搜一搜。
今天介绍一下django中的session。
Django中的session是一个中间件,可以倒入这个包查看。django.contrib.sessions.middleware
代码语言:javascript复制import time
from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
from django.utils.importlib import import_module
class SessionMiddleware(object):
def process_request(self, request):
engine = import_module(settings.SESSION_ENGINE)
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
request.session = engine.SessionStore(session_key)
def process_response(self, request, response):
"""
If request.session was modified, or if the configuration is to save the
session every time, save the changes and set a session cookie.
"""
try:
accessed = request.session.accessed
modified = request.session.modified
except AttributeError:
pass
else:
if accessed:
patch_vary_headers(response, ('Cookie',))
if modified or settings.SESSION_SAVE_EVERY_REQUEST:
if request.session.get_expire_at_browser_close():
max_age = None
expires = None
else:
max_age = request.session.get_expiry_age()
expires_time = time.time() max_age
expires = cookie_date(expires_time)
# Save the session data and refresh the client cookie.
# Skip session save for 500 responses, refs #3881.
if response.status_code != 500:
request.session.save()
response.set_cookie(settings.SESSION_COOKIE_NAME,
request.session.session_key, max_age=max_age,
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
path=settings.SESSION_COOKIE_PATH,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
return response
Django中的session是一个中间件,可以倒入这个包查看。django.contrib.sessions.middleware
从上面可以看到session这个中间件的源码其实非常简单。
我们先来看看process_request这个函数。这个函数是请求来的时候调用的。
他首先是加载了一个引擎,就是下面讲到的五种session的模式,可以在setting中自己设置。
然后是去request对象中的cookie 拿到SESSION_COOKIE_NAME,SESSION_COOKIE_NAME也是自己设置的,一般设置成”seesionid”
然后是从引擎中拿到数据。放在request对象的session中。
所以,其实我们的sessionid是从请求的cookie里拿到的,然后在这个中间件里根据sessionid去查找存储在服务器上的数据,然后设置在request对象的session里。
在看process_response这个函数。
我们看到有两个值,accessed 和modified.我们可以在SessionBase这个对象里看到这两个值,
在读取等操作以后,accessed就会被设置成True
在设置等操作以后,modified就会被设置成False
具体哪些操作会被设置,可以在SessionBase中查看。
在代码中可以看到,如果被访问过,那么respone 会把cookie这个字符串放在vary头部中
如果修改过,会进行一个判断:get_expire_at_browser_close
可以看一下这个函数的描述:
Returns ``True`` if the session is set to expire when the browser closes, and ``False`` if there's an expiry date. Use ``get_expiry_date()`` or ``get_expiry_age()`` to find the actual expiry date/age, if there is one.
这一部分其实就是对过期时间对一个设置。
如果返回不为500的话,就把session保存,然后把sessionid/过期时间等信息设置到cookie中返回给client。
介绍一下session的流程
django中的session是需要配合cookie一起使用的。步骤如下:
1.在发起请求的时候,服务器通过django的session设置信息,并生成唯一的session_id。
例如发起请求的user,他的id为1,名字为root
request.session[‘id’] = 1
request.session[‘name’] = ‘root’
这样session就设置好了,django中会把键值对存到一张表中
2.server在处理完请求以后,sessionid返回并存在cookie中
3.client再次访问该server,会带着之前cookie去访问
在服务器端,django直接使用request对象中的session,既可以拿到该client对应的sessionid里的所有信息。
例如获取id和name
Id = request.session.get(“id”)
Name = request.session.get(“name”)
Django中提供了五种模式的session供开发者使用:
1.数据库,这种是默认模式,即sessionid 和data是存在数据表中的
2.缓存
3.文件
4.缓存 数据库
5.加密cookie
我们可以在代码中看到这些被取名engine,其实从名字上也可以看出来,这些模式或者叫引擎到区分大多是根据存储的形式进行区分。
讲点实用的,django中如何操作session,即session的一些基本方法:
1.写session
request.session[key] = value
2.读session
value = request.session.get(key,”default”)
value = request.session[key]
3.清空session
request.session.clear()
4.删除session 数据,并在存储中删除整条数据
request.session.flush()
5.删除某个key
del request.session[key]
6.设置session有效时间
request.session.set_expiry(value)