flask提交表单

用户使用表单向服务器提交信息,比如最常见的登录,本文讲解如何在html页面里提交表单,flask如何处理表单数据,此外还将讨论表单敏感信息如何存储。下面是一个简单的登录页面中的form表单

<form action="/login" method="POST">
      <p>name: <input type="text" name="name" /></p>
      <p>password: <input type="password" name="password" /></p>
      <input type="submit" value="提交" />
</form>
  • action 设置提交的url
  • method 设置请求的方法
  • input标签的type设置为password时,在页面输入信息时不会显示明文

在服务端,接收表单信息的方式如下

@app.route('/login', methods=['GET', 'POST'])
def do_login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        name = request.form['name']
        password = request.form['password']
        if name == 'python':
            return render_template('index.html', name=name)
        else:
            return redirect('/login')

通过request.form来获取表单信息,然后要对用户输入的用户名和密码做校验,这里只是为了做演示,因此判断逻辑很简单,真正的产品里,需要拿着用户名和密码去数据库的user表里去查询,如果能找到用户,则说明用户名和密码是正确的。

生产环境下,用户的密码也并不是明文存储,比如你注册网站的时候,填写的密码是888888,网站不会明文存储这个密码,比较简单的做法是存储它的md5值

import hashlib
password = '888888'
bpwd = bytes(password, encoding='utf-8')

m = hashlib.md5()
m.update(bpwd)

md5_pwd = m.hexdigest()
print(md5_pwd)

888888的md5值是 21218cca77804d2ba1922c33e0151105,这样,即便你在数据库里看到这个数值,你也不知道它真实的密码是什么。

需要明确指明一点,md5不是加密算法,而是密码散列函数,它是一种单向函数,也就是说极其难以由散列函数输出的结果,回推输入的数据是什么,但是同一个值经过md5计算后的值是不会发生变化的,这样,你只要记住21218cca77804d2ba1922c33e0151105是888888的md5值,就可以对user表进行撞库处理了,网上所谓的md5解密,其实就是事先掌握了海量的密码和与之对应的md5值,然后通过md5反向查找原始密码。

md5值作为密码不够安全,你可以使用werkzeug.security模块里的generate_password_hash和check_password_hash函数。

generate_password_hash是密码加盐哈希函数,对同一个密码,每一次加密都会得到不同的值,generate_password_hash是密码验证函数,并不是反向计算出原始密码哦

下面是一段示例代码

from werkzeug.security import generate_password_hash, check_password_hash

# 对密码进行加密
password = generate_password_hash("888888")
print(password)

# 检查密码是否正确
result = check_password_hash(password, '888888')
print(result)

多次运行你就会发现,每次得到的password都是不同的,但是check_password_hash都能正确验证。

使用这两个函数,就绝对能够防止破解了么?当然不是,黑客还是可以在得到user表后进行暴力破解,但是暴力破解的难度和成本都增加了。

888888经过generate_password_hash函数处理后,会得到无数种加密结果,因此,就无法维护一个加密结果与原始密码的映射表,当你拿到一个加密后的密码后,你当然可以使用check_password_hash(password, '888888')来判断这个密码是不是888888加密后的结果,如果是,你运气好,一下子就蒙对了,但如果不是呢,你怎么办? 你只能尝试其他密码,比如123456,可是这样一来,工作量就太大了,常用的简单密码起码有几十万种,user表里的每一个密码都要尝试几十万次。

但不管怎样,如果你的密码很简单,黑客还是有机会破解,所以,最安全的做法是设置一个复杂一点的密码,让黑客破解密码的成本大到他不愿意承受。

本文所使用代码git地址为 https://github.com/kwsy/studyflask/tree/master/form

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案