Flask Web 开发 用户认证

来源:互联网 发布:mysql数据库的面试题 编辑:程序博客网 时间:2024/05/05 09:30

进入第二部分了,估计会很难,第一部分还有好多点的原理没搞清楚,不过先做起来吧。


用户认证其实说简单点就是用户名和密码是否匹配的过程。下面这段书里面的文档,应该说说的比较详细,就直接复制了

设计Web 程序时,人们往往会高估数据库中用户信息的安全性。如果攻击者入侵服务器获取了数据库,用户的安全就处在风险之中,这个风险比你想象的要大。众所周知,大多数
用户都在不同的网站中使用相同的密码,因此,即便不保存任何敏感信息,攻击者获得存储在数据库中的密码之后,也能访问用户在其他网站中的账户。
若想保证数据库中用户密码的安全,关键在于不能存储密码本身,而要存储密码的散列值。计算密码散列值的函数接收密码作为输入,使用一种或多种加密算法转换密码,最终
得到一个和原始密码没有关系的字符序列。核对密码时,密码散列值可代替原始密码,因为计算散列值的函数是可复现的:只要输入一样,结果就一样。


用户认证这一块功能,我们要开始用到werkzeug工具包了,里面用于认证密码的部分,我们需要用到security模块中的2个功能


generate_password_hash(password, method=pbkdf2:sha1, salt_length=8):这个函数将
原始密码作为输入,以字符串形式输出密码的散列值,输出的值可保存在用户数据库中。
method 和salt_length 的默认值就能满足大多数需求。
check_password_hash(hash, password):这个函数的参数是从数据库中取回的密码散列
值和用户输入的密码。返回值为True 表明密码正确。


而密码认证这一块,我们应该放在models里面进行设置

首先from werkzeug.security import generate_password_hash, check_password_hash

随后,在User的类里面,进行属性添加



计算密码散列值的函数通过名为password 的只写属性实现。设定这个属性的值时,赋值方法会调用Werkzeug 提供的generate_password_hash() 函数,并把得到的结果赋值给password_hash 字段。如果试图读取password 属性的值,则会返回错误,原因很明显,因为生成散列值后就无法还原成原来的密码了。
verify_password 方法接受一个参数( 即密码), 将其传给Werkzeug 提供的check_password_hash() 函数,和存储在User 模型中的密码散列值进行比对。如果这个方法返回
True,就表明密码是正确的。


随后我们进行密码的设置和测试


我们可以看到,你就算创建了u和u2的密码是相同的,他散列化以后出来的值也是不一样的

而且你如果在设置密码后尝试去访问u2的password属性,他会报错,因为密码已经被散列化了。


另外说个题外话:

在模型被修改后,数据库里的数据模型其实并没有被修改,所以我觉得应该是后期需要用到数据库迁移了才会更新数据库





接着课本上要求注册不同的蓝本了,这里插一句我对于blueprint的理解

看了网上很多的讲解,都说蓝本是将功能模块化,也就是将功能区分开

我实际上不是很理解,不过后来我看到每个注册的蓝图包下面,都会有一个views,就觉得,blueprint的作用其实是将每个功能分开,核心是将views模块打散

这样,views就不用一股脑写在一个文件里面了,不然到后期维护,一个views几千条,就得累死。


首先我们讲

为auth模块注册蓝图

app/auth/__init__.py:创建蓝本
from flask import Blueprint
auth = Blueprint('auth', __name__)
from . import views


app/auth/views.py:蓝本中的路由和视图函数
from flask import render_template
from . import auth
@auth.route('/login')
def login():
return render_template('auth/login.html')               #由于是注册了auth模块,所以,他读取的是auth文件夹里面的模板,而这个模板文件夹,必须在app/templates下面创建

#因为Flask 认为模板的路径是相对于程序模板文件夹而言的。


auth 蓝本要在create_app() 工厂函数中附加到程序上,如示例8-5 所示。
app/__init__.py:附加蓝本


def create_app(config_name):
# ...
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')     #注册蓝本时使用的url_prefix 是可选参数。如果使用了这个参数,注册后蓝本中定义的
return app                                                                                       #所有路由都会加上指定的前缀,即这个例子中的/auth。例如,/login 路由会注册成/auth/
                                                                                                          #login,在开发Web 服务器中,完整的URL 就变成了http://localhost:5000/auth/login

这里关于url_prefix这个前缀有个

首先第一点:重复一下,如果设置了url_prefix这个参数,那么在templates下面,必须要有对应的blueprint名字的文件夹,蓝图的视图函数读取的是那个里面的模板

比如,auth蓝图,他读取的是app/templates/auth/xxxxx.html

当然,你也可以读取templates根目录下面的html文件,那就需要你就要把注册蓝图时候的url_prefix去掉,并在路由里面返回的时候,把前置路径去掉即可,如果他读取不到你所范围的html,那么他就会报404,这个例子中,我们用test.html来做测试。



我们将main蓝图不设置url_prefix,则他读取的应该是templates根目录下的test.html





当然,如果我们强行修改路由参数的范围值,他也可以指定到文件夹内部去



我对这部分知识的理解是:通过在蓝图注册时候的参数url_prefix,你可以选择是否有前缀

而具体返回哪个路径的模板文件,你还是要在views里面修改,但貌似不是默认强制读取蓝图文件夹的,而是作为一种规范










0 0
原创粉丝点击