如果在运行文件中放置调试器,您将看到用户密码被哈希,但是当您查看mongo集合时,用户的密码将以纯文本格式存储。如何将用户密码保存为哈希?
以下是我的文件:
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, 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()
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": game,
}
答案 0 :(得分:3)
您run.py
中的一些主要内容阻止您进行身份验证:
create_user
事件挂钩中,您使用bcrypt.gensalt()
生成了一个盐,但您无法在任何地方保存盐。 Salts对于防止rainbow table攻击非常有用,但您需要保存它们,以便在尝试再次对密码进行哈希处理时获得相同的结果。on_insert_accounts
事件挂钩在文档发布之前修改文档,但随后返回post_internal
而不是让事件挂钩运行。这个可能有效,但我觉得你应该按照预期使用事件钩子。以下是修改后的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
}
答案 1 :(得分:0)
我做了这样的事情,以安全地存储我的用户密码,并阻止没有授权密钥的管理员创建:
class TokenAuthCutom(TokenAuth):
def check_auth(self, token, allowed_roles, resource, method):
payload = decode_token(token)
# check if payload is valid and if allowed_roles is not empty check if role is valid
return payload and (not allowed_roles or payload['roles'] in allowed_roles)
def before_insert_user(documents):
body = request.get_json(force=True)
admin_key = body.get('admin_register_key')
for document in documents:
password = document['password'].encode('utf-8')
document['password'] = bcrypt.hashpw(password, bcrypt.gensalt()).decode('utf-8')
document['roles'] = 'admin' if admin_key is not None and admin_key == ADMIN_REGISTER_KEY else 'client'
if __name__ == '__main__':
app = Eve(auth=TokenAuthCutom)
app.on_insert_users += before_insert_user
app.run(host=HOST, port=PORT)