三十三、python學習之Flask框架(五)模板:WTF表單、CSRF跨站請求偽造、模板特有函式&變數
一、WTF表單:
1.web表單:
Web 表單是 Web 應用程式的基本功能。預設開啟CSRF保護功能
它是HTML頁面中負責資料採集的部件。表單有三個部分組成:表單標籤、表單域、表單按鈕。表單允許使用者輸入資料,負責HTML頁面資料採集,通過表單將使用者輸入的資料提交給伺服器。
在Flask中,為了處理web表單,我們可以使用 Flask-WTF 擴充套件,它封裝了 WTForms,並且它有驗證表單資料的功能。
2.WTForms支援的HTML標準欄位:
欄位物件 | 說明 |
StringField | 文字欄位 |
TextAreaField | 多行文字欄位 |
PassWordField | 密碼文字欄位 |
HiddenField | 隱藏文字欄位 |
DateField | 文字欄位,值為datetime.date文字格式 |
DateTimeField | 文字欄位,值為datetime.datetime文字格式 |
InterField | 文字欄位,值為整數 |
DecimalField | 文字欄位,值為decimal.Decimal |
FloatField | 文字欄位,值為浮點數 |
BooleanField | 複選框,值為True和False |
RadioField | 一組單選框 |
SelectField | 下拉列表 |
SelectMutipleField | 下拉列表,可選擇多值 |
FileField | 檔案上傳欄位 |
SubmitField | 表單體檢按鈕 |
FormField | 把表單作為欄位嵌入到另一個表單 |
FieldList | 一組指定型別的欄位 |
3.WTForm常用驗證函式:
驗證函式 | 說明 |
DataRequired | 確保欄位中有資料 |
EqualTo | 比較兩個欄位的值,常用於比較兩次密碼輸入 |
Length | 驗證輸入的字串長度 |
NumberRange | 驗證輸入的值在數字範圍內 |
URL | 驗證URL |
AnyOf | 驗證輸入值在可選列表中 |
NoneOf | 驗證輸入值不在可選列表中 |
4.WTForm的程式碼演示:
檢視函式:
匯入模組:
from flask import Flask,render_template, request, flash
# 匯入flask_etf擴充套件包提供的表單類
from flask_wtf import FlaskForm
# 匯入wtf提供的欄位
from wtforms import StringField, PasswordField, SubmitField
# 匯入wtf擴充套件提供的驗證函式
from wtforms.validators import DataRequired, EqualTo
建立例項, 設定祕鑰值
app = Flask(__name__)
# 設定祕鑰,對提交的表單資料進行加密
app.config['SECRET_KEY'] = "ilovepython"
建立表單類:
# 自定義表單類:實現註冊的表單,文字框、密碼、確認密碼、提交
class Form(FlaskForm):
usr = StringField("使用者名稱", validators=[DataRequired("請填寫使用者名稱")])
pswd = PasswordField("密碼", validators=[DataRequired("請填寫密碼")])
pswd2 = PasswordField("確認密碼", validators=[DataRequired("請填寫確認密碼"), EqualTo("pswd")])
submit = SubmitField("提交")
建立檢視函式:
# 定義是檢視函式
@app.route("/demo01", methods=["GET", "POST"])
def demo02():
form = Form()
if form.validate_on_submit():
# 獲取表單提交的資料
usr = form.usr.data
pswd = form.pswd.data
pswd2 = form.pswd2.data
print("usr:" + str(form.usr))
# 假裝提交成功
print(usr, pswd, pswd2)
print(form.validate_on_submit())
print(form.validate_on_submit())
return render_template("demo01_wtf.html", form = form)
啟動程式
if __name__ == '__main__':
app.run(debug=True)
表單模板檔案.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ request.method }}</title>
</head>
<body>
{# 註冊頁面 #}
<form method="post">
{{ form.csrf_token }}
<p>{{ form.usr.label }}: {{ form.usr }}</p>
<p>{{ form.pswd.label }}: {{ form.pswd }}</p>
<p>{{ form.pswd2.label }}:{{ form.pswd2 }}</p>
<p>{{ form.submit }}</p>
</form>
</body>
</html>
三、 CSRF跨站請求偽造(二):
1.跨站請求偽造的流程:
1.1 跨站請求偽造的過程:
a.使用者登入正常的網站;
b.網站將cookie寫入伺服器,實現狀態保持;
c.使用者在未登出時,訪問了惡意的釣魚網站;
d.使用者在主觀未知的情況下, 像正常網站傳送了惡意網站偽造實現的請求;
2 .問題:
- a.攻擊正常網站的請求是使用者發起的
- b.惡意網站如何獲取正常網站的資訊:
-
- 釣魚:誰咬鉤釣誰
3 .跨站請求防護的實現:
csrf_token是一個隨機數,令牌,每次請求都會生成一個新的值;
1.後端伺服器首先需要開啟csrf保護,會驗證post/put/delete/patch請求, 一般不會驗證ge請求;
2.後端生成csrf_token, 會存入瀏覽器的cookie中,其次會存入表單中;
3.使用者請求,cookie中的csrf_token會自動攜帶,後端比較cookie找那個的csrf_tokrn好人表中的是否一致;
4.如果不一致,請求則為假.
4.模擬CSRF跨站偽造請求攻擊:
三、模板中特有的變數和函式
-
config
你可以從模板中直接訪問Flask當前的config物件:{{config.SQLALCHEMY_DATABASE_URI}} sqlite:///database.db
-
request
就是flask中代表當前請求的request物件:{{request.url}} http://127.0.0.1
-
session
為Flask的session物件{{session.new}} True
-
g變數
在檢視函式中設定g變數的 name 屬性的值,然後在模板中直接可以取出{{ g.name }}
-
url_for()
url_for會根據傳入的路由器函式名,返回該路由對應的URL,在模板中始終使用url_for()就可以安全的修改路由繫結的URL,則不比擔心模板中渲染出錯的連結:{{url_for('home')}} /
如果我們定義的路由URL是帶有引數的,則可以把它們作為關鍵字引數傳入url_for(),Flask會把他們填充進最終生成的URL中:
{{ url_for('post', post_id=1)}}
/post/1
- get_flashed_messages()
這個函式會返回之前在flask中通過flask()傳入的訊息的列表,flash函式的作用很簡單,可以把由Python字串表示的訊息加入一個訊息佇列中,再使用get_flashed_message()函式取出它們並消費掉:
{%for message in get_flashed_messages()%}
{{message}}
{%endfor%}