1、安全存储密码
密码不要以明文的形式直接存储在数据库中,以防被攻击者盗取、泄露。一般的做法是,不存储密码本身,而存储通过密码生成的散列值。(但密码仍然可能在传输过程中被截获)
from werkzeug.security import generate_password_hash, check_password_hash
password_hash = generate_password_hash('cat')
is_right = check_password_hash(password_hash, 'cat')
疑惑:加盐散列值、密码扩展,是什么样的作用原理?
2、创建管理员用户
可以提供一个博客初始化命令,以免手动在数据库中,使用sql语句添加管理员用户记录。
@app.cli.command()
@click.option('--username', prompt=True, help='The username used to login.')
@click.option('--password', prompt=True, hide_input=True,
confirmation_prompt=True, help='The password used to login.')
def init(username, password):
# 创建管理员记录相关的操作
...
将prompt
参数设置为True会在用户没有输入参数值时,请求用户输入。hide_input
用于隐藏输入内容,confirmation_prompt
用于要求二次输入确认。
博客程序需要根据用户的身份开放不同的功能,扩展Flask-Login
提供了用户会话管理功能,管理用户的登入、登出,以及视图保护(如要求某些视图登录后才能访问)功能。(p275)
不过,这些功能即使自己利用session
对象手动实现,也比较简单。
关于对资源的更新和删除操作,为了防止csrf攻击,应当使用POST方法提交这类请求,即使用表单提交。但为每个这样的操作都需要单独定义一个WTForms表单类,显然太过麻烦。Flask-WTF内置的CSRFProtect扩展为这类操作提供了更简单的方式。
使用该csrf保护,首先需要初始化扩展,并注册到程序实例。
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect()
csrf.init_app(app)
然后直接在表单中创建一个csrf的隐藏字段。
<form method="post" action="{{ url_for('delete_post', post_id=post.id) }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
...
form>
并且你可以注册一个错误处理函数,捕捉程序中产生的csrf错误,并产生对应的响应。
from flask_wtf.csrf import CSRFError
@app.errorhandler(CSRFError)
def handle_csrf_error(e):
return render_template('errors/400.html', description=e.description), 400
1、文章管理——删除确认弹窗
在后台管理中可以查看文章列表,并删除其中的文章,删除通常是不可恢复的。因此,为了防止误触,我们需要添加一个删除确认弹窗,使用浏览器内置的confirm弹窗组件即可实现。
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?');">
删除
button>
…
这一小结的其它内容都是一些比较简单的、面向业务逻辑的考虑,就不继续介绍了
Flask-Admin扩展:可以简化你编写管理后台的工作。(p297)
这个项目,书中足足用了80页来介绍,涉及的内容确实比较丰富。我在看的时候有些赶进度,走马观花,快速带过。大部分的知识点都没有经过我的实践去体会,又只能把这个任务留给以后去完成了啊!