一:发送邮件
1、安装 Flask-Mail 扩展
pip install Flask-Mail
2、Flask-Mail应用配置
可以在app.config中进行配置。
MAIL_SERVER:email的smtp服务器IP或主机名,默认为localhost。
MAIL_PORT:email的smtp服务器端口,默认为25。
MAIL_USE_TLS:启用/禁用传输安全层加密,默认为 False。
MAIL_USE_SSL:启用/禁用安全套接字层加密,默认为 False。
MAIL_DEBUG:设置debug支持,默认为app.debug。
MAIL_USERNAME:设置用户名,默认为 None。
MAIL_PASSWORD:设置用户密码,默认为 None。
MAIL_DEFAULT_SENDER:设置默认发送用户,默认为None。
MAIL_MAX_EMAILS:设置发送最大邮件数,默认为None。
MAIL_ASCII_ATTACHMENTS:如果设置成True,附件文件名将会转换成 ASCII。默认为 False。
示例:
app.config['MAIL_SERVER'] = 'smtp.aliyun.com'
app.config['MAIL_PORT'] = 25
app.config['MAIL_USERNAME'] = 'xxx@aliyun.com'
app.config['MAIL_PASSWORD'] = 'xxx'
3、 Mail类
创建Mail对象 Mail(app)
Mail类方法:
send_message(*args, **kwargs):发送邮件的简洁方法。
send(message):发送邮件方法,参数是message对象。
connect():打开服务器连接对象,连接对象可以直接发送邮件,用于发送大量邮件。
示例:
mail = Mail(app)
...
mail.send_message(subject='你好',
sender='zhijieketang@aliyun.com',
body='你好,这是来自于Flask-Mail的邮件。',
recipients=['270258799@qq.com', 'eorient@sina.com'])
4、Message类
Message类构造函数主要参数:
subject: 邮件主题。
recipients:接收邮件列表。
body:邮件内容。
html:HTML格式的邮件内容。
sender:发送邮件地址。
cc:抄送邮件列表。
bcc:密送邮件列表。
date:邮件日期。
charset:邮件编码。
Message类attach()方法可以发送附件。
示例:
msg = Message('你好',
sender='zhijieketang@aliyun.com',
recipients=['270258799@qq.com', 'eorient@sina.com'])
msg.body = '你好,这是来自于Flask-Mail的邮件。'
# 添加附件
with app.open_resource("a.jpg") as fp:
msg.attach("a.jpg", "image/jpg", fp.read())
mail.send(msg)
二:WTF表单
Flask-WTF扩展提供了WTForm表单,增强表单功能:
增强表单验证:Web应用程序的表单中的输入字段,需要进行验证,“凡有输入,必有验证”。
防止CSRF(Cross Site Request Forgery)攻击,即跨站伪造请求攻击。WTForm表单可以生成一个CSRF令牌。
方便渲染页面。
1、安装 Flask-WTF扩展
pip install flask-WTF
2、自定义WTForm表单类
class RegistrationForm(Form):
username = StringField('用户名:', [validators.required('请输入用户名')])
...
3、WTForm字段类
StringField:渲染为<input type = 'text'>的HTML元素,只能放置字符串。
IntegerField:渲染为<input type = 'text'>的HTML元素,只能放置整数。
DecimalField:渲染为<input type = 'text'>的HTML元素,只能放置小数。
PasswordField:渲染为<input type = 'password'>的HTML元素。
BooleanField:渲染为<input type = 'checkbox'>的HTML元素。
RadioField:渲染为<input type = 'radio'>的HTML元素。
SelectField:渲染为<select>的HTML元素,即下拉菜单。
TextAreaField:渲染为<testarea>的HTML元素。
SubmitField:渲染为<input type = 'submit'>的HTML元素。
4、validators模块中验证器类
DataRequired:验证字段是否为空。别名required。
Email:验证email是否有效。
IPAddress:验证是否是有效的IP地址。
Length:验证字符串的长度是否在给定的范围内。
NumberRange:验证数字是否在给定的范围内。
URL:验证是否是有效的URL。
EqualTo:验证两个字段内容是否相等。
示例:
class RegistrationForm(Form):
username = StringField('用户名:', [validators.DataRequired('请输入用户名')])
password = PasswordField('密码:', [validators.DataRequired('请输入密码')])
password2 = PasswordField('再次输入密码:', [validators.EqualTo('password', message='两次输入的密码不匹配')])
email = StringField('邮箱:', [validators.DataRequired('请输入邮箱'), validators.Email('请输入有效的邮箱')])
二、
用户注册示例:
1、编写表单类
2、编写表单类对应的模板文件
3、显示验证错误信息
4、防止CSRF攻击
三、CSRF攻击原理及过程
假设网站A为存在CSRF漏洞的网站,网站B是攻击者的恶意网站,用户C为网站A的合法用户。
1 、用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A。
2、用户C通过验证后,网站A产生Cookie信息并返回给用户C的浏览器,此时用户登录网站A成功,可以正常发送请求到网站A。
3、用户C退出网站A之前,在同一浏览器中,打开另外一个浏览器标签访问网站B。
4、网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A。
5、浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户C不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
第三:
一、什么是对象关系映射
大部分编程语言都是面向对象的,采用对象模型。而数据被保存在关系数据库中的,数据采用的是关系模式。
关系模型和对象模型是有区别的,对象模型更加先进,能够描述继承、实现、关联、聚合和组成等复杂的关系,而关系模型只能描述一对一、一对多和多对多的关系。这两种模型之间的不和谐称为“阻抗不匹配”问题,而ORM可以解决“阻抗不匹配”问题。
SQLAlchemy是一种ORM(对象关系映射)技术。ORM是关系数据模型和对象模型类之间的一个纽带。
二、SQLAlchemy使用
1、安装SQLAlchemy:
pip install flask-sqlalchemy
2、初始化SQLAlchemy引擎
from sqlalchemy import create_engine
...
DB_FILES = 'db/database.db'
engine = create_engine('sqlite:///' + DB_FILES, echo=True)
create_engine第一个参数是数据库连接,不同数据库不同:
MySQL数据库:"mysql://scott:tiger@hostname/dbname"
MySQL数据库+Pymysql:"mysql+pymysql://scott:tiger@hostname/dbname"
Postgres数据库:"postgresql://scott:tiger@hostname/dbname"
Sqlite数据库:"sqlite:///数据库文件路径"
echo参数:设置为True,输出SQL执行语句。
3、定义数据模型
from sqlalchemy import Column
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
...
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
name = Column('username', String(100), primary_key=True)
password = Column('password', String(100))
email = Column('email', String(50))
4、创建数据库表
if __name__ == '__main__':
Base.metadata.create_all(engine)
5、创建数据库Session对象
Session = sessionmaker(bind=engine)
session = Session()
Session对象类似于数据库的连接对象,常用方法:
session.add(new_user):插入数据。
session.delete(user):删除用户。
session.commit():提交数据库事物。
session.rollback():回滚数据库事物。
session.close():关闭session。
session.query(User):查询方法,返回查询对象Query。
文档http://docs.sqlalchemy.org/en/latest/orm/session.html
三、示例
1、查询所有数据
# 查询所有数据
def find_all():
Session = sessionmaker(bind=engine)
session = Session()
# 查询返回的列表
list = session.query(User).all()
# 返回给视图的列表
list2 = []
for user in list:
dict = {}
dict['username'] = user.name
dict['password'] = user.password
dict['email'] = user.email
list2.append(dict)
# 关闭session
session.close()
return list2
2、插入数据
def create(user):
Session = sessionmaker(bind=engine)
session = Session()
new_user = User(name=user['username'],
password=user['password'],
email=user['email'])
session.add(new_user)
# 提交数据库事物
session.commit()
# 关闭session
session.close()
3、删除数据
def remove(username):
Session = sessionmaker(bind=engine)
session = Session()
# 查询用户
user = session.query(User).filter_by(name=username).one()
# 删除用户
session.delete(user)
# 提交数据库事物
session.commit()
# 关闭session
session.close()