1. 程式人生 > >三十三、python學習之Flask框架(五)模板:WTF表單、CSRF跨站請求偽造、模板特有函式&變數

三十三、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 驗證輸入值不在可選列表中
使用Flask-WTF需要配置引數 SECRET_KEY. CSRF_ENABLED是為了CSRF(跨站請求偽造)保護。 SECRET_KEY用來生成加密令牌,當CSRF啟用的時候,該設定會根據設定的密匙生成加密令牌。

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跨站偽造請求攻擊:

點選下載: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%}