Flask快速入門(17) — flask_session

Flask快速入門(17) — flask_session

做用:將默認保存的簽名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),#這個配置文件控制
相關文章
相關標籤/搜索