Python 如何从会话中删除特定密钥(用于当前会话)?
我使用Flask kvsession来避免重播攻击,因为Flask登录使用的基于客户端cookie的会话很容易受到重播攻击。 例如:如果在/索引页面上,标题中的cookie是为应用标题设置的,如 myapp_会话:“值1” 如果您导航到/important页面,您将得到一个新的标题,如 myapp_会话:“value2”,因此如果黑客获得“value1”,他可以执行重播攻击并滥用它,因为它永远不会失效 为了解决这个问题,我使用了flask kvsession,它将会话cookie头值存储在缓存或某个后端中。因此,基本上只有一个myapp_会话在您注销时生成并失效。但问题是:-Python 如何从会话中删除特定密钥(用于当前会话)?,python,session,flask,flask-login,flask-kvsession,Python,Session,Flask,Flask Login,Flask Kvsession,我使用Flask kvsession来避免重播攻击,因为Flask登录使用的基于客户端cookie的会话很容易受到重播攻击。 例如:如果在/索引页面上,标题中的cookie是为应用标题设置的,如 myapp_会话:“值1” 如果您导航到/important页面,您将得到一个新的标题,如 myapp_会话:“value2”,因此如果黑客获得“value1”,他可以执行重播攻击并滥用它,因为它永远不会失效 为了解决这个问题,我使用了flask kvsession,它将会话cookie头值存储在缓存或
__init__.py
from simplekv.memory.redisstore import RedisStore
import redis
store = RedisStore(redis.StrictRedis())
#store = memcache.Client(['127.0.0.1:11211'], debug =0)
store.ttl_support = True
app = create_app(__name__)
current_kvsession = KVSessionExtension(store, app)
如果您查看kv会话代码的cleanup_会话部分
它只删除过期的会话。但是,如果我想在注销时为特定用户显式删除当前myapp_会话的值,我该怎么做
@app.before_request
def redirect_if_logout():
if request.path == url_for('logout'):
for key in app.kvsession_store.keys():
logger.debug(key)
m = current_kvsession.key_regex.match(key)
logger.debug('found %s', m)
app.kvsession_store.delete(key)
但这会删除所有密钥,因为我不知道当前会话的唯一密钥是什么
问题2。另外,如何使用memcache而不是redis,因为它没有app.kvsession\u store.keys()函数,并且会出现i/o错误。我想我刚刚了解了您问题的第一部分,即如何在注销时删除特定的密钥 如文件所述: 在内部,会话存储序列化为的会话ID 已创建密钥,其中密钥是一个随机数(会话“true”id)和 创建会话创建时间的UNIX时间戳 在客户端创建的cookie值示例(您可以使用firefox的cookie管理器扩展进行检查): c823af88aedaf496_571b3fd5.4kv9X8UvyQqtCtNV87jTxy3Zcqc 和作为密钥存储在redis中的会话id: c823af88aedaf496_571b3fd5 因此,在注销处理程序上,您只需要读取cookie值,拆分它并使用字符串的第一部分: 适用于我的示例代码:
import redis
from flask import Flask
from flask_kvsession import KVSessionExtension
from simplekv.memory.redisstore import RedisStore
store = RedisStore(redis.StrictRedis())
app = Flask(__name__)
KVSessionExtension(store, app)
#Logout Handler
@app.route('/logout', methods=['GET'])
def logout():
#here you are reading the cookie
cookie_val = request.cookies.get('session').split(".")[0]
store.delete(cookie_val)
由于您添加了ttl_支持:
store.ttl_support = True
如果您在配置文件或app.py文件的开头设置了TTL(秒),它将与永久会话生命周期中的TTL(秒)值相匹配
例如,在我的应用程序中,我在app.py文件的开头设置为:
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=5)
现在,当我注销时,它会删除redis中的密钥,但直到该密钥的TTL从300变为0(永久会话生存期值中提到的5分钟),它才会被删除
如果您想立即将其从redis中删除,您可以手动将app.permanent_session_生存期更改为1秒,这将反过来更改redis的TTL
import redis
import os
from flask import Flask
from flask_kvsession import KVSessionExtension
from simplekv.memory.redisstore import RedisStore
store = RedisStore(redis.StrictRedis())
app = Flask(__name__)
KVSessionExtension(store, app)
#Logout Handler
@app.route('/logout', methods=['GET'])
def logout():
cookie_val = request.cookies.get('session').split(".")[0]
app.permanent_session_lifetime = timedelta(seconds=1)
store.delete(cookie_val)
使用上述代码,我能够阻止会话重播攻击
第二个问题的答案:
我看到的3个可能的错误是:
1:在您创建的代码的开头:
store = RedisStore(redis.StrictRedis())
但在循环中,您将其用作kvsession_存储,而不仅仅是存储:
app.kvsession_store.keys()
store.keys()
而不是app.store.keys():
store.delete(key)
并不是删除所有的键,而是在一个接一个删除所有键的循环中运行它from flask_kvsession import KVSessionExtension
from simplekv.memory.redisstore import RedisStore
store = RedisStore(redis.StrictRedis())
for key in store.keys():
print key