做用:將默認保存的簽名cookie中的值,保存到 redis/memcached/file/Mongodb/SQLAlchemypython
安裝:pip install flask-sessionredis
使用1:sql
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這個類mongodb
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:flask
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)源碼:cookie
def init_app(self, app): app.session_interface = self._get_interface(app) # 在這裏重寫了session_interface
self._get_interface(app)源碼:session
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失效。app
response.set_cookie('k','v',exipre=None)#這樣設置便可 #在session中設置 app.session_interface=RedisSessionInterface(conn,key_prefix='lqz',permanent=False) #通常不用,咱們通常都設置超時時間,多長時間後失效
問題:cookie默認超時時間是多少?如何設置超時時間dom
#源碼expires = self.get_expiration_time(app, session) 'PERMANENT_SESSION_LIFETIME': timedelta(days=31),#這個配置文件控制