Flask快速入门(17) — flask_session

Flask快速入门(17) — flask_session

作用:将默认保存的签名cookie中的值,保存到 redis/memcached/file/Mongodb/SQLAlchemy

安装:pip install flask-session

使用1:

from flask import Flask,session
from flask_session import RedisSessionInterface
import redis
app = Flask(__name__)
conn=redis.Redis(host=‘127.0.0.1‘,port=6379)  # 连接redis

# use_signer是否对key签名
# 如果use_siginer为False,这表示不需要配置app.secret_key
app.session_interface=RedisSessionInterface(conn,key_prefix=‘lqz‘)
@app.route(‘/‘)
def hello_world():
    session[‘name‘]=‘lqz‘
    return ‘Hello World!‘

if __name__ == ‘__main__‘:
    app.run()

我们知道session是从app.session_interface入口。所以要改变存储位置的话,要重写app.session_interface。在这里的RedisSessionInterface重写了open_session(取)和save_session(存)。我们来看看RedisSessionInterface这个类

class RedisSessionInterface(SessionInterface):
    serializer = pickle
    session_class = RedisSession
    # 实例化参数:redis连接的redis; key_prefix存储的前缀; user_signer是否对key签名,为False则不需要设置secret_key,为True时,需要设置; permanent关闭浏览器是否保存,为Frue保存,为False不保存
    def __init__(self, redis, key_prefix, use_signer=False, permanent=True):
        if redis is None:
            from redis import Redis
            redis = Redis()
        self.redis = redis
        self.key_prefix = key_prefix
        self.use_signer = use_signer
        self.permanent = permanent

    def open_session(self, app, request):
        sid = request.cookies.get(app.session_cookie_name)
        if not sid:
            sid = self._generate_sid()
            return self.session_class(sid=sid, permanent=self.permanent)
        if self.use_signer:
            signer = self._get_signer(app)
            if signer is None:
                return None
            try:
                sid_as_bytes = signer.unsign(sid)
                sid = sid_as_bytes.decode()
            except BadSignature:
                sid = self._generate_sid()
                return self.session_class(sid=sid, permanent=self.permanent)

        if not PY2 and not isinstance(sid, text_type):
            sid = sid.decode(‘utf-8‘, ‘strict‘)
        val = self.redis.get(self.key_prefix + sid)  # 从redis中取出session
        if val is not None:
            try:
                data = self.serializer.loads(val)  # 获取session反序列化值
                return self.session_class(data, sid=sid)
            except:
                return self.session_class(sid=sid, permanent=self.permanent)
        return self.session_class(sid=sid, permanent=self.permanent)

    def save_session(self, app, session, response):
        domain = self.get_cookie_domain(app)
        path = self.get_cookie_path(app)
        if not session:
            if session.modified:
                self.redis.delete(self.key_prefix + session.sid)
                response.delete_cookie(app.session_cookie_name,
                                       domain=domain, path=path)
            return
        httponly = self.get_cookie_httponly(app)
        secure = self.get_cookie_secure(app)
        expires = self.get_expiration_time(app, session)
        val = self.serializer.dumps(dict(session))  # 将session序列化放入val中
        # 将session设置到redis,name=前缀+字符串,value=session值
        self.redis.setex(name=self.key_prefix + session.sid, value=val,
                         time=total_seconds(app.permanent_session_lifetime))
        if self.use_signer:
            session_id = self._get_signer(app).sign(want_bytes(session.sid))
        else:
            session_id = session.sid
        response.set_cookie(app.session_cookie_name, session_id,
                            expires=expires, httponly=httponly,
                            domain=domain, path=path, secure=secure)

使用2:

from flask import Flask,session
from redis import Redis
from flask_session import Session
app = Flask(__name__)
app.config[‘SESSION_TYPE‘] = ‘redis‘
app.config[‘SESSION_REDIS‘] = Redis(host=‘127.0.0.1‘,port=‘6379‘)
Session(app)

@app.route(‘/‘)
def index():
    session[‘name‘] = ‘nick‘
    return ‘hello‘

@app.route(‘/index‘)
def test():
    return session[‘name‘]

if __name__ == ‘__main__‘:
    app.run()

主要是通过配置SESSION_TYPE源码中进行相应的存储:Session(app)源码

def __init__(self, app=None):
    self.app = app
    if app is not None:
        self.init_app(app)

self.init_app(app)源码:

def init_app(self, app):
    app.session_interface = self._get_interface(app)  # 在这里重写了session_interface

self._get_interface(app)源码:

def _get_interface(self, app):
    # 在这里做了一些相关的配置
    config = app.config.copy()
    config.setdefault(‘SESSION_TYPE‘, ‘null‘)
    config.setdefault(‘SESSION_PERMANENT‘, True)
    config.setdefault(‘SESSION_USE_SIGNER‘, False)
    config.setdefault(‘SESSION_KEY_PREFIX‘, ‘session:‘)
    config.setdefault(‘SESSION_REDIS‘, None)
    config.setdefault(‘SESSION_MEMCACHED‘, None)
    config.setdefault(‘SESSION_FILE_DIR‘,
                      os.path.join(os.getcwd(), ‘flask_session‘))
    config.setdefault(‘SESSION_FILE_THRESHOLD‘, 500)
    config.setdefault(‘SESSION_FILE_MODE‘, 384)
    config.setdefault(‘SESSION_MONGODB‘, None)
    config.setdefault(‘SESSION_MONGODB_DB‘, ‘flask_session‘)
    config.setdefault(‘SESSION_MONGODB_COLLECT‘, ‘sessions‘)
    config.setdefault(‘SESSION_SQLALCHEMY‘, None)
    config.setdefault(‘SESSION_SQLALCHEMY_TABLE‘, ‘sessions‘)

    # 通过if...elif...else来判断匹配config[‘SESSION_TYPE‘],再执行相应的session_interface
    if config[‘SESSION_TYPE‘] == ‘redis‘:
        session_interface = RedisSessionInterface(
            config[‘SESSION_REDIS‘], config[‘SESSION_KEY_PREFIX‘],
            config[‘SESSION_USE_SIGNER‘], config[‘SESSION_PERMANENT‘])
    elif config[‘SESSION_TYPE‘] == ‘memcached‘:
        session_interface = MemcachedSessionInterface(
            config[‘SESSION_MEMCACHED‘], config[‘SESSION_KEY_PREFIX‘],
            config[‘SESSION_USE_SIGNER‘], config[‘SESSION_PERMANENT‘])
    elif config[‘SESSION_TYPE‘] == ‘filesystem‘:
        session_interface = FileSystemSessionInterface(
            config[‘SESSION_FILE_DIR‘], config[‘SESSION_FILE_THRESHOLD‘],
            config[‘SESSION_FILE_MODE‘], config[‘SESSION_KEY_PREFIX‘],
            config[‘SESSION_USE_SIGNER‘], config[‘SESSION_PERMANENT‘])
    elif config[‘SESSION_TYPE‘] == ‘mongodb‘:
        session_interface = MongoDBSessionInterface(
            config[‘SESSION_MONGODB‘], config[‘SESSION_MONGODB_DB‘],
            config[‘SESSION_MONGODB_COLLECT‘],
            config[‘SESSION_KEY_PREFIX‘], config[‘SESSION_USE_SIGNER‘],
            config[‘SESSION_PERMANENT‘])
    elif config[‘SESSION_TYPE‘] == ‘sqlalchemy‘:
        session_interface = SqlAlchemySessionInterface(
            app, config[‘SESSION_SQLALCHEMY‘],
            config[‘SESSION_SQLALCHEMY_TABLE‘],
            config[‘SESSION_KEY_PREFIX‘], config[‘SESSION_USE_SIGNER‘],
            config[‘SESSION_PERMANENT‘])
    else:
        session_interface = NullSessionInterface()
    return session_interface

问题:设置cookie时,如何设定关闭浏览器则cookie失效。

response.set_cookie(‘k‘,‘v‘,exipre=None)#这样设置即可
#在session中设置
app.session_interface=RedisSessionInterface(conn,key_prefix=‘lqz‘,permanent=False)
#一般不用,我们一般都设置超时时间,多长时间后失效

问题:cookie默认超时时间是多少?如何设置超时时间

#源码expires = self.get_expiration_time(app, session)
‘PERMANENT_SESSION_LIFETIME‘:           timedelta(days=31),#这个配置文件控制

原文地址:https://www.cnblogs.com/863652104kai/p/11708074.html

时间: 2024-08-27 15:30:43

Flask快速入门(17) — flask_session的相关文章

网站后端_Python+Flask.0003.FLASK快速入门之Hello Word?

框架特点: 1. 非常小, 小到可称为微型框架 2. 可扩展, 设计初衷就是不会替开发者做太多决策,支持随时更换或动手实现扩展模块 3. 三依赖, 路由/调试/WSGI(由WERKZEUG提供的WEB服务器网关接口实现),模版系统(由JINJA2实现),签名(由ITSDANGEROUS实现) 快速安装: pip install flask 快速入门: #!/usr/bin/env python # -*- coding: utf-8 -*- """ # # Authors: 

Flask快速入门(18) — 信号

Flask快速入门(18) - 信号 作用:Flask框架中的信号基于blinker,其主要就是让开发者可以在flask请求过程中定制一些用户行为 安装:pip install blinker 内置信号: request_started = _signals.signal('request-started') # 请求到来前执行 request_finished = _signals.signal('request-finished') # 请求结束后执行 before_render_templ

Flask快速入门(20) — 多app应用

Flask快速入门(20) - 多app应用 之前一直是一个app,如果有多个app该怎么进行分发呢? from werkzeug.wsgi import DispatcherMiddleware from werkzeug.serving import run_simple from flask import Flask,current_app # 注册两个app app1 = Flask('app01') app2 = Flask('app02') @app1.route('/index')

【转】Flask快速入门

迫不及待要开始了吗?本页提供了一个很好的 Flask 介绍,并假定你已经安装好了 Flask.如果没有,请跳转到 安装 章节. 一个最小的应用 一个最小的 Flask 应用看起来会是这样: from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run() 把它保存为 hello.py 

Flask快速入门,知识整理

一.Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来) Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器. “微”

flask快速入门笔记三_上下文对象:Flask核心机制

首先声明:内容大部分来自huizhiwang,只是单纯记笔记. 1 请求 :WSGI WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口. WSGI将Web服务分成两个部分:服务器和应用程序.WGSI服务器只负责与网络相关的两件事:接收浏览器的 HTTP请求.向浏览器发送HTTP应答:而对HTTP请求的具体处理

flask快速入门

概述: Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 (类似于php中的smarty,旨在让程序实现界面与数据分离). Flask使用 BSD 授权. WSGI(Python Web Server Gateway Interface),是Python应用程序或框架和Web服务器之间的一种接口,已经被广泛接受.类似于java中的servelet api. 一个最简单的应用: from flask im

flask快速入门笔记四_模板:分离数据与视图

首先声明:内容大部分来自huizhiwang,只是单纯记笔记. 1 模板引擎 在Flask中,视图函数的返回值为响应的正文被送往前端浏览器.毫无疑问,一个实用 的视图函数需要在服务端根据请求的不同动态构造这个内容.然而手工拼接一段冗长 的HTML串是乏味而且相当容易出错. 这正是模板引擎发挥威力的地方,只需要将模板和数据送入模板引擎,我们就告 别了那些那些拼接.转义之类的琐碎之事,轻松得到一个渲染后的字符串:

二 Flask快速入门

1: 外部可访问的服务器: 如果你运行了这个服务器,你会发现它只能从你自己的计算机上访问,网络中其它任何的地方都不能访问.在调试模式下,用户可以在你的计算机上执行任意 Python 代码.因此,这个行为是默认的.如果你禁用了 debug 或信任你所在网络的用户,你可以简单修改调用 run() 的方法使你的服务器公开可用,如下: app.run(host='0.0.0.0'),这会让操作系统监听所有公网 IP. 2: 调试模式 虽然 run() 方法适用于启动本地的开发服务器,但是你每次修改代码后