1. 做好准备工作
- 进入项目主目录
- 激活虚拟环境
2. 密码哈希
Werkzeug是Flask的核心依赖之一,其中的security模块可以方便的实现哈希值的计算,你安装了Flask,Werkzeug就已经包含在里面了。下面的Python shell会话演示了如何通过Werkzeug的 generate_password_hash 函数哈希密码:
>>> from werkzeug.security import generate_password_hash
>>> hash = generate_password_hash('foobar')
>>> hash
'pbkdf2:sha256:50000$vT9fkZM8$04dfa35c6476acf7e788a1b5b3c35e217c78dc04539d295f011f01f18cd2175f'
在这个例子中,foobar 被转换成哈希值,由于转换是不可逆的,所以就算有人获得了哈希过的密码,也无法得到原始的密码。另外,如果多次哈希相同的密码,得到的结果也是不同的,因此无法通过查看它们的哈希值来确定两个用户是否具有相同的密码。
验证过程由Werkzeug模块的 check_password_hash 函数来完成:
>>> from werkzeug.security import check_password_hash
>>> check_password_hash(hash, 'foobar')
True
>>> check_password_hash(hash, 'barfoo')
False
验证函数对比之前生成的密码哈希值和用户在登录时输入的密码,如果两个值匹配,则返回 True,否则返回False。
在用户模型中编写两个新方法,实现哈希逻辑:
app/models.py
from werkzeug.security import generate_password_hash, check_password_hash
# ...
class User(db.Model):
# ...
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
现在用户对象就可以实现安全密码验证了,而不需要明文存储密码:
>>> u = User(username='susan', email='susan@example.com')
>>> u.set_password('mypassword')
>>> u.check_password('anotherpassword')
False
>>> u.check_password('mypassword')
True
3. 使用 Flask-Login
Flask-Login模块用于管理用户的登录状态,比如说,它可以“记住”登录的用户,然后访问其他有登录限制的页面。
先在虚拟环境中安装Flask-Login:
(venv) $ pip install flask-login
和其他的拓展一样,Flask-Login需要在__init__.py中的应用实例的后面初始化:
# ...
from flask_login import LoginManager
app = Flask(__name__)
# ...
login = LoginManager(app)
# ...
4. 修改用户模型
Flask-Login配合应用的用户模型使用,在用户模型中作为方法来实现,以下是Flask-Login要求实现的四个方法:
- is_authenticated: 如果用户已经登录,返回True,否则返回False的属性
- is_active: 如果用户已激活,返回True,否则返回False的属性
- is_anonymous: 如果是登录用户,返回False, 否则返回True的属性
- get_id():返回用户的唯一标识符字符串(Python2中为unicode)的方法
实现这四个方法很简单,但是实现过程很无聊,所以Flask-Login提供了一个名为UserMixin的mixin类,其中包含大部分用户模型类的默认实现,添加这个类的方法很简单: