1 session源码
1.1 save_session
1.2 open_session
1.3 django session的控制
2 闪现
3 请求扩展
1 app.session_interface 默认是某个类的对象,以后全局对象 session,就是SecureCookieSessionInterface()的对象
2 请求来了,会执行这个对象的: open_session方法
3 请求走了,会执行这个对象的:save_session方法
4 找出上面讲的--》读源码--》
app.run()---->run_simple(地址, 端口, self可调用对象)--->self 是谁?就是 app
请求来了,就会执行 self可调用对象()--->app()---->对象加括号---》触发---》类的__call__
请求来了,就会执行flask类的 __call__--->self.wsgi_app(environ, start_response)
def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any:
ctx = self.request_context(environ)
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except: # noqa: B001
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if "werkzeug.debug.preserve_context" in environ:
environ["werkzeug.debug.preserve_context"](_cv_app.get())
environ["werkzeug.debug.preserve_context"](_cv_request.get())
if error is not None and self.should_ignore_error(error):
error = None
ctx.pop(error)
# 5 ctx.push()--->有如下代码
if self.session is None: # 请求刚来,是空的
#session_interface 就是SecureCookieSessionInterface类的对象
self.session = session_interface.open_session(self.app, self.request)
if self.session is None:
self.session = session_interface.make_null_session(self.app)
#6 SecureCookieSessionInterface类的open_session
from flask.sessions import SecureCookieSessionInterface
open_session步骤:
1 会去cookie中取出session对应的 三段式的字符串
2 解密,校验签名---》把这个数据--》放到 session对象中
save_session步骤:
1 从session取出数据
2 加密,签名---放到cookie中
3 返回给前端
'''
1 视图函数中,咱们 session[name]=lqz
2 请求走了,会触发save_session
3 触发save_session时:
把session中的数据,加密签名得到三段字符串
放到cookie中,放到了浏览器中
'''
def save_session(
self, app: Flask, session: SessionMixin, response: Response
) -> None:
name = self.get_cookie_name(app)
domain = self.get_cookie_domain(app)
path = self.get_cookie_path(app)
secure = self.get_cookie_secure(app)
samesite = self.get_cookie_samesite(app)
httponly = self.get_cookie_httponly(app)
# Add a "Vary: Cookie" header if the session was accessed at all.
if session.accessed:
response.vary.add("Cookie")
# If the session is modified to be empty, remove the cookie.
# If the session is empty, return without setting the cookie.
if not session:
if session.modified:
response.delete_cookie(
name,
domain=domain,
path=path,
secure=secure,
samesite=samesite,
httponly=httponly,
)
response.vary.add("Cookie")
return
if not self.should_set_cookie(app, session):
return
expires = self.get_expiration_time(app, session)
# 加密,签名---放到cookie中
val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore
response.set_cookie(
name,
val, # type: ignore
expires=expires,
httponly=httponly,
domain=domain,
path=path,
secure=secure,
samesite=samesite,
)
response.vary.add("Cookie")
'''
1 请求来了,request中带着cookie(也有可能没有)
2 根据 session这个key,取出value,如果有,就是 我们当时生成的三段
3 字典=s.loads(value) 把内容验签,解密出来,转成了字典
4 把这个字典转到 session对象中
5 以后视图函数中 session[name] 就能取到当时你放的name
'''
def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None:
s = self.get_signing_serializer(app)
if s is None:
return None
# val 就是那三段
val = request.cookies.get(self.get_cookie_name(app))
if not val:
# 如果没有带cookie,造个空session,返回
return self.session_class()
max_age = int(app.permanent_session_lifetime.total_seconds())
try:
data = s.loads(val, max_age=max_age)
# 解密,校验签名---》把这个数据--》放到 session对象中
return self.session_class(data)
except BadSignature:
return self.session_class()
from django.contrib.sessions.middleware import SessionMiddleware
Django 中的 Session 控制主要涉及到用户会话的管理。会话是指在用户与 web 服务器之间的一段时间内,服务器可以存储关于用户的信息的机制。Django 使用 Session 来存储用户的会话信息。
以下是 Django 中关于 Session 控制的一些建议和常用操作:
1. **启用 Session Middleware:** 确保 `django.contrib.sessions.middleware.SessionMiddleware` 被添加到 `MIDDLEWARE` 配置中。
2. 这是用于处理 session 的中间件。
3. **配置 Session 引擎:** Django 支持多种 Session 引擎,包括数据库引擎、缓存引擎等。
4. 在 `settings.py` 文件中,通过设置 `SESSION_ENGINE` 来选择使用的引擎。例如:
# settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
5. **Session 的过期时间:** 可以通过 `SESSION_COOKIE_AGE` 设置 Session 的过期时间,以秒为单位。默认是 1209600 秒(2 周)。
# settings.py
SESSION_COOKIE_AGE = 1209600 # 2 weeks in seconds
6. **Session 的存储位置:** 如果选择使用数据库引擎,可以通过 `SESSION_SAVE_EVERY_REQUEST` 设置是否在每个请求中保存 Session 数据。
# settings.py
SESSION_SAVE_EVERY_REQUEST = True
7. **Session 的清理:** Django 提供了 `clearsessions` 管理命令,用于清理过期的 Session 数据。
python manage.py clearsessions
8. **Session 的使用:** 在视图中,你可以通过 `request.session` 来访问和设置 Session 数据。
# views.py
def set_session(request):
request.session['username'] = 'john'
return HttpResponse("Session data set.")
def get_session(request):
username = request.session.get('username', 'Guest')
return HttpResponse(f"Hello, {username}.")
9. **Session 的删除:** 你可以通过 `del request.session['key']` 或者 `request.session.pop('key', None)` 来删除 Session 中的某个键。
Django 的 Session 控制提供了一种灵活和可定制的方式来管理用户的会话信息,
可以根据项目的需求进行相应的配置。
# flash 翻译过来的
# 假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息
# 以后遇到,在当次请求有数据要存,下次请求还能取出来,就可以使用闪现
### 设置闪现
# 1 普通使用 :通过闪现---》放进去,取一次,就没了
# flash(s) # 放到闪现中了,加密放到了cookie总
# 2 分类,以分类放入
flash(s, category='xxx')
flash('xxx', category='yyy')
### 取闪现
# 1 普通取,全取出来 从闪现中取出来
# err = get_flashed_messages()[0]
# 2 根据分类取
err = get_flashed_messages(category_filter=['xxx'])[0]
# 总结:
1 设置flash,可以按分类设置
2 去flash,在当前请求中,可以取出多次,都是在的
3 一旦有请求取出,再去别的的请求中取,就没了,无论有没有分类,都没了
# django 中中间件,对所有请求拦截
# flask中使用请求扩展实现
django flask
-process_request----》before_request
-process_response--->after_request
# 就是django中间件
请求头中判断有没有user-agent 做反扒
响应头中加入 跨域的
from flask import Flask, session, redirect, request, flash, get_flashed_messages,make_response
app = Flask(__name__)
app.secret_key = 'asdfasdf'
app.debug = True
@app.before_request
def before():
# 做统一处理,处理校验失败,不让他继续往后走了
'''
return None---->继续走下一个请求扩展
return 新手四件套
'''
print('来了')
@app.before_request
def before2():
# 做统一处理,处理校验失败,不让他继续往后走了
'''
return None---->继续走下一个请求扩展
return 新手四件套
'''
print('来了222')
# return '不行了'
@app.after_request
def after(response):
print('走了')
# return response
return make_response('你看到我了')
@app.route('/')
def home():
print('home')
return 'home'
@app.route('/order')
def order():
return 'order'
if __name__ == '__main__':
app.run()