如果您将调试器放在运行文件中,您将看到用户的密码被散列,但是当您查看 mongo 集合时,用户的密码以纯文本形式存储。如何将用户密码保存为哈希值?
这是我的文件:
运行.py:
from eve import Eve
from eve.auth import BasicAuth
import bcrypt
class BCryptAuth(BasicAuth):
def check_auth(self, username, password, allowed_roles, resource, method):
# use Eve's own db driver; no additional connections/resources are used
accounts = app.data.driver.db["accounts"]
account = accounts.find_one({"username": username})
return account and \
bcrypt.hashpw(password, account['password']) == account['password']
def create_user(*arguments, **keywords):
password = arguments[0][0]['password']
username = arguments[0][0]['username']
user = {
"password": bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()),
"username": username,
}
return post_internal("accounts", user)
app = Eve(auth=BCryptAuth)
app.on_insert_accounts += create_user
if __name__ == '__main__':
app.run()
设置.py:
API_NAME = "gametest"
CACHE_CONTROL = "max-age=20"
CACHE_EXPIRES = 20
MONGO_DBNAME = "gametest"
MONGO_HOST = "localhost"
MONGO_PORT = 27017
PUBLIC_ITEM_METHODS = ["GET"]
RESOURCE_METHODS = ["GET"]
accounts_schema = {
"username": {
"type": "string",
"required": True,
"unique": True,
},
"password": {
"type": "string",
"required": True,
},
}
accounts = {
# the standard account entry point is defined as
# '/accounts/<ObjectId>'. We define an additional read-only entry
# point accessible at '/accounts/<username>'.
"additional_lookup": {
"url": "regex('[\w]+')",
"field": "username",
},
# We also disable endpoint caching as we don't want client apps to
# cache account data.
"cache_control": "",
"cache_expires": 0,
# Finally, let's add the schema definition for this endpoint.
"schema": accounts_schema,
"public_methods": ["POST"],
"resource_methods": ["POST"],
}
games_schema = {
"game_id": {
"type": "objectid",
"required": True
},
"title": {
"type": "string",
"required": True
},
}
games = {
"item_title": "game",
"schema": games_schema,
}
orders = {
"schema": {
"game": {
"type": "objectid",
"required": True,
},
},
"resource_methods": ["GET", "POST"],
}
DOMAIN = {
"accounts", accounts,
"orders": orders,
"games": game,
}
最佳答案
您的 run.py
中有一些主要问题阻止您进行身份验证:
- 在
create_user
事件 Hook 中,您使用bcrypt.gensalt()
生成盐,但没有将盐保存在任何地方。盐可用于预防rainbow table攻击,但您需要保存它们,以便当您再次尝试对密码进行哈希处理时,您会得到相同的结果。 - 您使用
on_insert_accounts
事件 Hook 在发布文档之前修改文档,但随后返回post_internal
而不是让事件 Hook 运行其进程。这可能有效,但我觉得您应该按照预期使用事件 Hook 。
这是修改后的run.py
:
from eve import Eve
from eve.auth import BasicAuth
import bcrypt
class BCryptAuth(BasicAuth):
def check_auth(self, username, password, allowed_roles, resource, method):
# use Eve's own db driver; no additional connections/resources are used
accounts = app.data.driver.db["accounts"]
account = accounts.find_one({"username": username})
return account and \
bcrypt.hashpw(password.encode('utf-8'), account['salt'].encode('utf-8')) == account['password']
def create_user(documents):
for document in documents:
document['salt'] = bcrypt.gensalt().encode('utf-8')
password = document['password'].encode('utf-8')
document['password'] = bcrypt.hashpw(password, document['salt'])
app = Eve(auth=BCryptAuth)
app.on_insert_accounts += create_user
if __name__ == '__main__':
app.run()
您的 settings.py
中存在一些拼写错误,因此我在此处提供了一个工作版本以供更好的衡量:
API_NAME = "gametest"
CACHE_CONTROL = "max-age=20"
CACHE_EXPIRES = 20
MONGO_DBNAME = "gametest"
MONGO_HOST = "localhost"
MONGO_PORT = 27017
PUBLIC_ITEM_METHODS = ["GET"]
RESOURCE_METHODS = ["GET"]
accounts_schema = {
"username": {
"type": "string",
"required": True,
"unique": True
},
"password": {
"type": "string",
"required": True
}
}
accounts = {
# the standard account entry point is defined as
# '/accounts/<ObjectId>'. We define an additional read-only entry
# point accessible at '/accounts/<username>'.
"additional_lookup": {
"url": "regex('[\w]+')",
"field": "username",
},
# We also disable endpoint caching as we don't want client apps to
# cache account data.
"cache_control": "",
"cache_expires": 0,
# Finally, let's add the schema definition for this endpoint.
"schema": accounts_schema,
"public_methods": ["POST"],
"resource_methods": ["POST"]
}
games_schema = {
"game_id": {
"type": "objectid",
"required": True
},
"title": {
"type": "string",
"required": True
}
}
games = {
"item_title": "game",
"schema": games_schema
}
orders = {
"schema": {
"game": {
"type": "objectid",
"required": True,
}
},
"resource_methods": ["GET", "POST"]
}
DOMAIN = {
"accounts": accounts,
"orders": orders,
"games": games
}
关于python - 在Eve中,如何安全地存储用户的密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27029842/