在 Flask-Login token_loader 中加载令牌会引发 "BadTimeSignature: timestamp missing"
Loading token in Flask-Login token_loader raises "BadTimeSignature: timestamp missing"
我想使用 Flask-Login 的 token_loader
加载登录用户。我只希望令牌对 REMEMBER_COOKIE_DURATION
配置中设置的值有效。当我尝试加载令牌时,我得到 BadTimeSignature: timestamp missing
。为什么会出现此错误以及如何解决?
@login_manager.token_loader
def load_token(token):
"""This metod is callback, which is used in
the Login Manager inner logic for retrieving
data from token.
:returns User instance or None if token
is invalid.
"""
max_age = app.config["REMEMBER_COOKIE_DURATION"].total_seconds()
data = login_serializer.loads(token, max_age=max_age)
user = get_user_by_id(data[0])
if user and data[1] == user.password:
return user
return None
line 418, in _load_from_cookie
user = self.token_callback(cookie)
File "/home/peter/Lv-164.UI/ecomap/src/python/ecomap/user.py", line 127, in load_token
data = login_serializer.loads(token, max_age = max_age)
File "/usr/local/lib/python2.7/dist-packages/itsdangerous.py", line 643, in loads
.unsign(s, max_age, return_timestamp=True)
File "/usr/local/lib/python2.7/dist-packages/itsdangerous.py", line 437, in unsign
raise BadTimeSignature('timestamp missing', payload=result)
BadTimeSignature: timestamp missing
您尝试加载的令牌不是使用 TimedSerializer
生成的,或者是无效的,因此无法找到时间戳进行比较。使用正确的序列化程序来生成和加载您的令牌。您还应该捕获这些异常并记录错误,因为仍然可以发送错误数据。
from flask import abort, flash
from itsdangerous import TimedSerializer, BadData, SignatureExpired
# define a timestamp serializer
login_serializer = TimedSerializer(app.secret_key, salt='login')
# generate the token with the user id (your example assumed a list)
token = login_serializer.dumps([user.id])
# load the token, but tell the user about expiration and log bad data
try:
data = login_serializer.loads(token, max_age=max_age)
except SignatureExpired:
flash('Login token is too old, you need to log in again.')
abort(401)
except BadData as e:
app.logger.exception('Bad login token "{}"', token)
abort(401)
将用户密码直接放在令牌中是不安全的,因为令牌只是签名,没有加密。攻击者可以看到用户的密码散列是什么并尝试破解它。相反,要么省略密码(因为他们只有在使用正确密码成功登录后才能获得令牌),或者将其与有关用户的其他信息进行哈希处理。
validation = hash((user.username, user.password))
token = login_serializer.dumps([user.id, validation])
data = login_serializer.loads(token, max_age=max_age)
user = get_user_by_id(data[0])
if hash((user.username, user.password)) != data[1]:
# did not validate
我想使用 Flask-Login 的 token_loader
加载登录用户。我只希望令牌对 REMEMBER_COOKIE_DURATION
配置中设置的值有效。当我尝试加载令牌时,我得到 BadTimeSignature: timestamp missing
。为什么会出现此错误以及如何解决?
@login_manager.token_loader
def load_token(token):
"""This metod is callback, which is used in
the Login Manager inner logic for retrieving
data from token.
:returns User instance or None if token
is invalid.
"""
max_age = app.config["REMEMBER_COOKIE_DURATION"].total_seconds()
data = login_serializer.loads(token, max_age=max_age)
user = get_user_by_id(data[0])
if user and data[1] == user.password:
return user
return None
line 418, in _load_from_cookie
user = self.token_callback(cookie)
File "/home/peter/Lv-164.UI/ecomap/src/python/ecomap/user.py", line 127, in load_token
data = login_serializer.loads(token, max_age = max_age)
File "/usr/local/lib/python2.7/dist-packages/itsdangerous.py", line 643, in loads
.unsign(s, max_age, return_timestamp=True)
File "/usr/local/lib/python2.7/dist-packages/itsdangerous.py", line 437, in unsign
raise BadTimeSignature('timestamp missing', payload=result)
BadTimeSignature: timestamp missing
您尝试加载的令牌不是使用 TimedSerializer
生成的,或者是无效的,因此无法找到时间戳进行比较。使用正确的序列化程序来生成和加载您的令牌。您还应该捕获这些异常并记录错误,因为仍然可以发送错误数据。
from flask import abort, flash
from itsdangerous import TimedSerializer, BadData, SignatureExpired
# define a timestamp serializer
login_serializer = TimedSerializer(app.secret_key, salt='login')
# generate the token with the user id (your example assumed a list)
token = login_serializer.dumps([user.id])
# load the token, but tell the user about expiration and log bad data
try:
data = login_serializer.loads(token, max_age=max_age)
except SignatureExpired:
flash('Login token is too old, you need to log in again.')
abort(401)
except BadData as e:
app.logger.exception('Bad login token "{}"', token)
abort(401)
将用户密码直接放在令牌中是不安全的,因为令牌只是签名,没有加密。攻击者可以看到用户的密码散列是什么并尝试破解它。相反,要么省略密码(因为他们只有在使用正确密码成功登录后才能获得令牌),或者将其与有关用户的其他信息进行哈希处理。
validation = hash((user.username, user.password))
token = login_serializer.dumps([user.id, validation])
data = login_serializer.loads(token, max_age=max_age)
user = get_user_by_id(data[0])
if hash((user.username, user.password)) != data[1]:
# did not validate