از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
اعتبار سنجی فرم فلاسک با Flask-WTF
سرفصلهای مطلب
معرفی
اعتبار سنجی فرم یکی از ضروری ترین اجزای ورود داده ها در برنامه های کاربردی وب است. کاربران ممکن است اشتباه کنند، برخی از کاربران بدخواه هستند. با اعتبارسنجی ورودی، از برنامه خود در برابر داده های بدی که بر منطق تجاری و ورودی های مخربی که به منظور آسیب رساندن به سیستم های ما تأثیر می گذارد محافظت می کنیم.
تلاش برای process ورودیهای نامعتبر کاربر میتوانند باعث بروز باگهای غیرمنتظره/غیرقابل رسیدگی شوند، در صورتی که خرابی سرور نباشد. در این زمینه، اعتبارسنجی داده ها به معنای تأیید ورودی و بررسی اینکه آیا انتظارات یا معیارهای خاصی را برآورده می کند یا خیر. اعتبار سنجی داده ها قابل انجام است روی هر دو قسمت جلو و عقب
در این آموزش، روش اعتبارسنجی ورودی کاربر در فرمهای Flask را با استفاده از Flask-WTForms افزونه.
در پایان این آموزش، فرم ثبت نام کاربر زیر را با معیارهای اعتبار سنجی خواهیم داشت:
ما از نسخه Flask استفاده خواهیم کرد 1.1.2 و Flask-WTF با نسخه 0.14.3.
برپایی
در حالی که ضروری نیست، توصیه می کنیم یک محیط مجازی ایجاد کنید تا آن را دنبال کنید:
$ mkdir flask-form-validation
$ cd flask-form-validation
$ python3 -m venv .
$ . bin/activate
در محیط مجازی فعال شده شما، بسته های خود را با تایپ کردن:
$ pip install Flask Flask-WTF
توجه داشته باشید که اگر می خواهید از اعتبارسنجی ایمیل استفاده کنید، باید آن را نیز نصب کنید email_validator
بسته (نسخه فعلی است 1.1.1):
$ pip3 install email_validator
حالا بیایید فایل های لازم خود را بسازیم. ما با ایجاد یک پایه شروع خواهیم کرد app.py
، که برای سادگی، شامل برنامه، مسیرها و فرمهای Flask ما خواهد بود:
from flask import Flask, render_template
app = Flask(__name__, template_folder='.')
app.config('SECRET_KEY')='LongAndRandomSecretKey'
ما یک شی Flask ایجاد کردیم و تنظیم کردیم template_folder
به پوشه فعلی سپس ما را اختصاص دادیم Flask
اعتراض به app
متغیر. اضافه کردیم SECRET_KEY
به ما app
پیکربندی شی
این SECRET_KEY
معمولاً برای رمزگذاری با اتصالات پایگاه داده و جلسات مرورگر استفاده می شود. WTForms از SECRET_KEY
به عنوان نمک برای ایجاد یک توکن CSRF. می توانید در مورد CSRF بیشتر بخوانید روی این ویکی page.
اگر برنامه شما قبلاً از SECRET_KEY
پیکربندی برای مقاصد دیگر، شما می خواهید یک مورد جدید برای WTForms ایجاد کنید. در این صورت می توانید تنظیم کنید WTF_CSRF_SECRET_KEY
پیکربندی
بیایید یک فرم ایجاد کنیم و به جریان خود اضافه کنیم app.py
:
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
class GreetUserForm(FlaskForm):
username = StringField(label=('Enter Your Name:'))
submit = SubmitField(label=('Submit'))
ساده ما GreetUserForm
کلاس شامل a StringField
. همانطور که از نام آن پیداست، این فیلد انتظار دارد و مقدار رشته ای را برمی گرداند (همیشه می توانید آن ورودی را در صورت نیاز به انواع داده های دیگر تبدیل کنید). نام رشته است username
، و از این نام برای دسترسی به داده های عنصر فرم استفاده می کنیم.
این label
پارامترها چیزی هستند که ارائه خواهند شد روی ما page به طوری که کاربران متوجه شوند که یک عنصر فرم چه داده هایی را جمع آوری می کند. ما همچنین یک submit
دکمه، که سعی می کند در صورتی که همه فیلدها معیارهای اعتبارسنجی ما را تأیید کنند، فرم را ارسال کند.
اکنون که راه اندازی شدیم، بیایید از WTForms برای اعتبارسنجی داده های خود استفاده کنیم!
اعتبار سنجی فرم فلاسک با Flask-WTForms
بیایید با ایجاد مسیری برای نمایش و شروع کنیم process فرم ما:
@app.route('/', methods=('GET', 'POST'))
def index():
form = GreetUserForm()
if form.validate_on_submit():
return f'''<h1> Welcome {form.username.data} </h1>'''
return render_template('index.html', form=form)
مسیر ما دارد GET
و POST
مواد و روش ها. این GET
متد فرم را نمایش می دهد، در حالی که POST
متد داده های فرم را پردازش می کند روی ارسال. ما مسیر URL را به /
، یا root URL، بنابراین به عنوان صفحه اصلی برنامه وب ما ظاهر می شود page. ما رندر می کنیم index.html
قالب و پاس کنید form
شی به عنوان یک پارامتر
بیایید مکث کنیم و به این خط توجه کنیم: if form.validate_on_submit():
. این قانون می گوید اگر روش درخواست باشد پست و اگر فیلد(های) فرم معتبر هستند، ادامه دهید. اگر ورودی فرم ما از معیارهای اعتبارسنجی ما عبور کند، روی بعدی page یک پیام خوشامدگویی ساده با نام کاربر ارائه می شود. توجه داشته باشید که در اینجا از نام فیلد (username
) برای دسترسی به داده های ورودی.
برای دیدن فرم باید فرم را ایجاد کنیم index.html
قالب. فایل را ایجاد کنید و کد زیر را به آن اضافه کنید:
<form method="POST" action="">
<div class="form-row">
<div class="form-group col-md-6">
{{ form.csrf_token() }}
<label for=""> {{ form.username.label }}</label>
{{ form.username }}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-primary")}}
</div>
</div>
</form>
ما از خود استفاده می کنیم form
شیء برای ارسال عناصر WTform به آن جینجا2 – تجزیه کننده قالب برای Flask.
توجه داشته باشید: csrf_token
به طور خودکار توسط WTForms تولید می شود و هر بار تغییر می کند page ارائه شده است. این به ما کمک می کند تا از سایت خود در برابر حملات CSRF محافظت کنیم. به طور پیش فرض، یک فیلد مخفی است. شما همچنین می توانید استفاده کنید {{ form.hidden_field() }}
برای رندر کردن تمام فیلدهای پنهان، از جمله توکن CSRF، اما توصیه نمی شود.
حالا بریم سراغ خودمون terminal برای شروع برنامه Flask ما با تایپ کردن:
$ FLASK_ENV=development flask run
برای راحتی، ما تنظیم می کنیم FLASK_ENV
متغیر محیطی به “توسعه” در حین توسعه. این به برنامه اجازه میدهد هر بار که ذخیره را فشار میدهیم، مجدداً بارگذاری شود. برای ویندوز ممکن است مجبور شوید استفاده کنید set FLASK_ENV=development
به شما terminal/console قبل از اجرای برنامه فلاسک
در اینجا چیزی است که اگر به آن بروید خواهیم دید localhost:
در قسمت ورودی یک نام تایپ کنید و فرم را ارسال کنید. پیام تبریکی را که ما در مسیر خود تعریف کردیم را مشاهده خواهید کرد:
همانطور که انتظار می رود کار می کند. اما اگر چیزی در فیلد ورودی تایپ نکردیم چه؟ همچنان فرم را تأیید می کند:
بیایید از این اتفاق جلوگیری کنیم و فقط به کاربرانی که نام خود را تایپ کردهاند اجازه دهیم موارد بعدی را ببینند page. برای انجام این کار، ما باید اطمینان حاصل کنیم که ما username
فیلد داده ورودی دارد.
خوب import یکی از روش های داخلی اعتبارسنجی WTForms: DataRequired()
از جانب wtforms.validators
و آن را به ما منتقل کنید username
رشته.
from wtforms.validators import ValidationError, DataRequired
class GreetUserForm(FlaskForm):
username = StringField(label=('Enter Your Name:'),
validators=(DataRequired()))
submit = SubmitField(label=('Submit'))
توجه داشته باشید که ما در حال عبور از validators
پارامتر به عنوان یک لیست این به ما می گوید که می توانیم برای هر فیلد چند اعتبار سنجی داشته باشیم.
حالا که استفاده می کنیم DataRequired()
، username
اگر دادههای ورودی وجود نداشته باشد، فیلد تأیید نمیشود:
در واقع، اگر ما روی عنصر فرم کلیک راست کرده و آن را بررسی کنیم، خواهیم دید که WTForms به طور خودکار required
ویژگی به فیلد ورودی:
با انجام این کار، WTForms یک اعتبار سنجی اولیه front-end را به فیلد فرم ما اضافه می کند. شما نمی توانید آن فرم را بدون آن ارسال کنید username
حتی اگر سعی کنید فرم را با استفاده از ابزارهایی مانند cURL یا Postman پست کنید.
حال، فرض کنید میخواهیم یک قانون اعتبارسنجی جدید تنظیم کنیم که فقط به نامهایی اجازه میدهد که حداقل 5 کاراکتر داشته باشند. ما می توانیم استفاده کنیم Length()
تایید کننده با min
پارامتر:
from wtforms.validators import ValidationError, DataRequired, Length
class GreetUserForm(FlaskForm):
username = StringField(label=('Enter Your Name:'),
validators=(DataRequired(), Length(min=5)))
submit = SubmitField(label=('Submit'))
اگر بخواهیم فرمی را با داده های ورودی کمتر از 5 کاراکتر ارسال کنیم، معیارهای اعتبارسنجی برآورده نخواهد شد و ارسال ناموفق خواهد بود:
کلیک کردن روی دکمه ارسال هیچ کاری برای داده های نامعتبر انجام نمی دهد، همچنین هیچ خطایی را به کاربر نمایش نمی دهد. ما باید پیام های خطا را ارائه کنیم تا کاربر بفهمد چه اتفاقی می افتد روی و چگونه باید این را تعمیر کنیم.
در ما index.html
الگو، درست در زیر {{ form.username }}
، حلقه for-loop Jinja2 زیر را برای نمایش خطاها اضافه کنید:
{% for field, errors in form.errors.items() %}
<small class="form-text text-muted ">
{{ ', '.join(errors) }}
</small>
{% endfor %}
فرم ما اکنون می تواند خطاهای اعتبارسنجی تمیز را ارائه دهد:
به هر دلیلی، اگر بخواهیم حداکثر طول دادههای فیلد خود را محدود کنیم، میتوانیم این کار را با عبور دادن انجام دهیم max
پارامتر به Length()
تایید کننده همچنین می توان پیام خطا را با ارسال یک پیام اختیاری سفارشی کرد message
پارامتر با یک رشته خطای سفارشی.
بیایید به روز رسانی کنیم username
فیلد بر این اساس:
class GreetUserForm(FlaskForm):
username = StringField(label=('Enter Your Name:'),
validators=(DataRequired(),
Length(min=5, max=64, message='Name length must be between %(min)d and %(max)dcharacters') ))
submit = SubmitField(label=('Submit'))
بیشتر فیلدهای WTForms و اعتبار سنجی با فرم ثبت نام کاربر
فرم فعلی ما یک فیلد واحد دارد که به نوعی کسل کننده است. WTForms معیارهای گسترده اعتبار سنجی فرم و انواع فیلدهای فرم را ارائه می دهد، بنابراین بیایید از آن استفاده کنیم و چیزی با استفاده عملی ایجاد کنیم.
ما یک فرم ثبت نام کاربر ایجاد می کنیم و از اعتبار سنجی WTForms داخلی استفاده می کنیم.
ما استفاده خواهیم کرد DataRequired()
اعتباردهنده فیلدهایی که میخواهیم مطمئن شویم کاربر آنها را پر میکند. حداقل و حداکثر طول فیلدها را بررسی میکنیم. Length()
اعتبار سنجی، اعتبارسنجی ایمیل ها با Email()
اعتبار سنجی و بررسی کنید که آیا دو فیلد دارای داده های یکسانی هستند EqualTo()
تایید کننده
را حذف کنید GreetUserForm
کلاس و شروع کد خود را با فرم جدید ما جایگزین کنید:
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, \
SubmitField
from wtforms.validators import ValidationError, DataRequired, \
Email, EqualTo, Length
class CreateUserForm(FlaskForm):
username = StringField(label=('Username'),
validators=(DataRequired(),
Length(max=64)))
email = StringField(label=('Email'),
validators=(DataRequired(),
Email(),
Length(max=120)))
password = PasswordField(label=('Password'),
validators=(DataRequired(),
Length(min=8, message='Password should be at least %(min)d characters long')))
confirm_password = PasswordField(
label=('Confirm Password'),
validators=(DataRequired(message='*Required'),
EqualTo('password', message='Both password fields must be equal!')))
receive_emails = BooleanField(label=('Receive marketing emails.'))
submit = SubmitField(label=('Submit'))
ما چهار زمینه مختلف در فرم های خود داریم. آخرین مورد یک دکمه ارسال معمولی است. ما با استفاده از StringField
برای دریافت ورودی رشته از کاربران، مانند username
و email
. از سوی دیگر، PasswordField
متن رمز عبور را پنهان می کند روی قسمت جلویی BooleanField
به عنوان یک چک باکس ارائه می شود روی جلویی چون فقط حاوی مقادیر True (بررسی شده) یا False (بررسی نشده) است.
باید اصلاح کنیم index.html
الگویی برای ارائه فیلدهای فرم جدید ما:
<div class="container">
<h2>Registration Form</h2>
{% for field, errors in form.errors.items() %}
{{ ', '.join(errors) }}
{% endfor %}
<form class="form-horizontal" method="POST" action="">
{{ form.csrf_token() }}
<div class="form-group">
{{ form.username.label }}
{{ form.username(class="form-control") }}
</div>
<div class="form-group">
{{ form.email.label }}
{{ form.email(class="form-control") }}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password(class="form-control") }}
</div>
<div class="form-group">
{{ form.confirm_password.label }}
{{ form.confirm_password(class="form-control") }}
</div>
<div class="form-group">
{{ form.receive_emails.label }}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-primary")}}
</div>
</form>
</div>
همانطور که می بینید، فیلدهای فرم ما به درستی ارائه شده اند:
توجه داشته باشید: اگر قرار است وب سایت شما چندین فرم مختلف داشته باشد، ممکن است بخواهید به جای تایپ هر فیلد فرم یکی یکی از ماکروهای Jinja2 استفاده کنید. استفاده از ماکروها از حوصله این مقاله خارج است، اما فرآیند ایجاد فرم را تا حد زیادی سرعت می بخشد.
ایجاد اعتبارسنجی سفارشی خود
در اکثر وب سایت ها، کاراکترهای خاصی در نام کاربری مجاز نیستند. این می تواند برای اهداف امنیتی باشد، می تواند برای لوازم آرایشی باشد. WTForms به طور پیش فرض چنین منطقی را ندارد، اما ما خودمان می توانیم آن را تعریف کنیم.
WTForms به ما اجازه می دهد تا با افزودن اعتبارسنجی، اعتبار سنجی سفارشی را اضافه کنیم روش به ما UserRegistrationForm
کلاس بیایید اعتبار سفارشی را با اضافه کردن آن در فرم خود پیاده سازی کنیم validate_username()
روش درست زیر submit
دکمه.
class UserRegistrationForm(FlaskForm):
submit = SubmitField(label=('Submit'))
def validate_username(self, username):
excluded_chars = " *?!'^+%&/()=})({$#"
for char in self.username.data:
if char in excluded_chars:
raise ValidationError(
f"Character {char} is not allowed in username.")
ما میتوانیم به تعداد یا چند روش اعتبارسنجی که دوست داریم اضافه کنیم. WTForms پس از تعریف، روش های اعتبارسنجی را به طور خودکار اجرا می کند.
این ValidationError
class راه مناسبی برای تعریف پیام اعتبارسنجی سفارشی به ما می دهد. توجه داشته باشید که نیاز خواهید داشت import آن را از wtforms.validators
قبل از استفاده از آن
بیایید این روش جدید را با وارد کردن دادههای مناسب در همه فیلدها به جز در آزمایش کنیم username
فیلد، که حاوی یک کاراکتر حذف شده – ‘%’ است.
همانطور که می بینید، روش اعتبارسنجی سفارشی ما به خوبی اجرا می شود و یک خطای اعتبار سنجی تمیز را به ما ارائه می دهد، که به ما کمک می کند تا بفهمیم چه چیزی با داده های ورودی ما اشتباه است. انجام این کار تجربه کاربر را تا حد زیادی بهبود می بخشد.
می توانید از کتابخانه های خارجی، پایگاه داده یا API ها برای ترکیب با WTForms و اعتبارسنجی داده های ورودی استفاده کنید. وقتی می خواهید عکس بگیرید {{ form.some_field.data }}
و در پایگاه داده بنویسید یا از آن درخواست کنید، از اعتبار سنجی WTForms برای اطمینان از ایمن بودن ذخیره آن استفاده کنید.
توجه داشته باشید: ما اکثر کدهای HTML را حذف کرده ایم زیرا مستقیماً با آموزش ما مرتبط نیستند. کد کامل در دسترس خواهد بود روی این مخزن GitHub، در صورتی که می خواهید بررسی کنید.
نتیجه
اعتبارسنجی داده ها یکی از ضروری ترین بخش های برنامه های وب Flask است. Flask-WTforms روش های بسیار قدرتمند و یادگیری آسانی را برای مدیریت داده های فرم ارائه می دهد.
اکنون که اصول اعتبارسنجی داده ها با Flask-WTF را می دانید، می توانید ادامه دهید و منطق اعتبارسنجی خود را اعمال کنید و/یا روش های خود را برای امنیت و تجربه کاربری بهتر پیاده سازی کنید.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-14 18:36:03