paint-brush
Pythonдо коопсуз форманы түзүү менен электрондук почтанын спамынан сактаныңыз тарабынан@tom2
327 окуулар
327 окуулар

Pythonдо коопсуз форманы түзүү менен электрондук почтанын спамынан сактаныңыз

тарабынан Rutkat11m2024/09/04
Read on Terminal Reader

өтө узун; Окуу

Жарактуу электрондук почта дареги – түз байланыш түзүү, лидерлерди түзүү, сатууларды алуу, онлайн коомдоштуктарга жеке чакыруулар ж.б.у.с. колдонмоңуз жана кызматтарыңыз. Биз колдонуучунун киргизүүсүн тазалоону, текшерүү шилтемесин түзүүнү жана маалымат базасы менен байланышты жөнөкөйлөтүүчү учурдагы Python модулдарын колдонобуз.
featured image - Pythonдо коопсуз форманы түзүү менен электрондук почтанын спамынан сактаныңыз
Rutkat HackerNoon profile picture

Жарактуу электрондук почта дареги түз байланыш түзүү, лидерлерди түзүү, сатууларды алуу, онлайн коомдоштуктарга жеке чакыруулар ж.б.у.с. Технологиянын эволюциясы аркылуу электрондук почта дагы эле туташуу үчүн сыналган жана чыныгы жолу болуп саналат. Биз нөлдөн баштап код кылбай, жөнөкөй нерселерди сактайбыз, анткени Python коддоону тездетүүгө жардам берген модулдары бар.


Мен кардарларымдын өнүмдөрүн илгерилетүү үчүн электрондук катталуу формаларын түзүүнү сурандым, бирок ал кардарлардын эч кимиси 3-тараптын тышкаркы кызматы үчүн ай сайын төлөгүсү келген жок, ошондуктан мен аларга ылайыкташтырылган байланыш формаларын түзүү менен акчаны үнөмдөп алдым. алар түбөлүккө колдоно алышат. Мен сизге стартап, кардар, маркетинг максаттары үчүнбү же эң жакшысы спамды азайтуу үчүн жардам бере алам.


Бул Pythonдо коддоону үйрөнүүнү каалагандар үчүн жана колдонуучунун киргизгенин чыпкалоо, электрондук почта даректерин текшерүү жана электрондук почтанын кош кошулуусу сыяктуу коопсуздук функцияларын эске албаган жаңы баштагандар үчүн өзгөчө пайдалуу. Бул окуу куралында биз 1-3 кадамдарды камтыйт:


  1. Жарактуу электрондук почта дареги үчүн колдонуучунун киргизгенин чыпкалоо
  2. Эки жолу катталуу
  3. Боттун/спамдын алдын алуу


Колдонмоңузга жана кызматтарыңызга жетүү үчүн Auth0, Facebook же Google сыяктуу үчүнчү тараптын кызматтарын колдонууга ишенүүнүн кереги жок, алар сизди каалаган убакта өчүрүп же дайындарыңызды бөлүшө алышат. Колдонмоңуздун дайындарын сиздикинде сактаңыз!


Баштоо менен сиз Python боюнча бир аз тажрыйбага ээ болушуңуз керек, анткени биз Flask алкагын MySQL маалымат базасы менен колдонобуз . Бул эң популярдуу CMS болгон WordPressти колдонууга караганда кызыктуураак (балким) болот. Акысыз Flask кеңейтүүсү менен бирдей мүмкүнчүлүккө ээ болуу үчүн кээ бир WordPress плагинине акча төлөшүңүз керек болот. Мен буга чейин Wordpress'те (PHP) курганмын жана Wordpress веб-тиркемелерди жасоого жөндөмдүү болсо да, веб-тиркемелер үчүн Python Flaskты жактырам.


Биз колдонуучунун киргизүүсүн тазалоону, текшерүү шилтемесин түзүүнү жана маалымат базасы менен байланышты жөнөкөйлөтүүчү учурдагы Python модулдарын колдонобуз.


Ар бир код үзүндүсү түшүндүрүлөт жана коддо айрым комментарийлер камтылат. Эгер сиз колдонуучунун каттоосун кура элек болсоңуз же анын ички иштерин билбесеңиз, мен сиз үчүн чоо-жайын сүрөттөп берем, анан аягында акыркы кодду көрө аласыз (өткөрүп жибербеңиз).


Бул жерде биринчи абзацта айтылгандай, биз ишке ашыра турган өзгөчөлүктөрдүн кыскача баяндамасы:


  1. Жарактуу электрондук почта дарегин кадимки туюнтманы же Flask кеңейтүүсүн колдонуучудан киргизүү сабын талдоо аркылуу текшерсе болот. Кокустук текстке же SQL инъекция түрүнө хакерлерге жол бербейбиз.


  2. Кош кошулуу ыкмасы алуучудан алардын келген кутусуна текшерүү шилтемесин алуу менен электрондук кат жөнөтүүгө уруксат берүүнү талап кылат. Бул, негизинен, башка бирөө сиздин электрондук почтаңыздын дарегин колдонууга жол бербөө үчүн колдонулат. Бул ошондой эле жөн гана катталып, каттоо эсептерин таштап койгон сыноо колдонуучуларынын алдын алат.


  3. Боттун алдын алуу колдонуучуга көрсөтүлбөгөн, бирок көбүнчө аялуу катталуу формаларын сойлоп жүргөн боттор тарабынан автоматтык түрдө толтурулган жашыруун талаа менен жүргүзүлүшү мүмкүн, бирок ал 3-тараптын кызматындагы "captcha" сыяктуу ишенимдүү эмес.


Келиңиз, коддоону баштайлы. Жумуш каталогун түзүү:

 mkdir signup cd signup


python3 -m venv signup же conda create -n double-opt-contact python3 аркылуу Python чөйрөңүздү түзүңүз. Мен конданы жактырам, эгер сиз көбүрөөк билгиңиз келсе, менин Python чөйрөлөрүндөгү макаламды окуй аласыз.


Төмөнкү көз карандылыкты орнотуу:
pip flask flask-mail secure SQLAlchemy Flask-WTF Flask-SQLAlchemy mysql-connector-python bleach

Же болбосо, requirements.txt файлында тизмеленген ошол эле көз карандылыктарга ээ болуп, pip install -r requirements.txt иштетсеңиз болот.


Төмөнкү көз карандылыктарды камтыган app.py файлын түзүңүз:


 from flask import Flask, render_template, request, url_for, redirect, flash from flask_mail import Mail, Message from datetime import datetime from flask_sqlalchemy import SQLAlchemy from sqlalchemy.sql import func from itsdangerous import URLSafeTimedSerializer, SignatureExpired import secrets import bleach


Колдонмонун объектисин демейки калып папкасынын жайгашкан жери менен инициализациялаңыз:

 app = Flask(__name__, template_folder='templates')


Бул саптарды колдонуп, өзүңүздүн сервер конфигурацияңыздын дайындарын киргизиңиз:

 secret = secrets.token_urlsafe(32) app.secret_key = secret app.config['SECRET_KEY'] = secret # auto-generated secret key # SQLAlchemy configurations app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqlconnector://admin:user@localhost/tablename' # Email configurations app.config['MAIL_SERVER'] = 'smtp.example.com' app.config['MAIL_PORT'] = 465 #check your port app.config['MAIL_USERNAME'] = '[email protected]' app.config['MAIL_PASSWORD'] = 'your_password' app.config['MAIL_USE_TLS'] = True app.config['MAIL_USE_SSL'] = False db = SQLAlchemy(app) mail = Mail(app) sserialzer = URLSafeTimedSerializer(app.config['SECRET_KEY']) #set secret to the serliazer


Акыр-аягы, конфигурация маалыматыңыз .env файлында болушу керек.


Кол менен же Python коду менен түзүлө турган колдонуучуларды сактоо үчүн бизге MySQL маалымат базасы керек болот. Окуу процессинин бир бөлүгү катары, сиз төмөнкү кодду буйрук сабын же Python'дун with app.app_context() db_create_all() ыкмасы менен киргизсеңиз болот.


Текшерилген талаа эки жолу кошулуу ыкмасын колдонууга мүмкүндүк берген токен саптары үчүн.

 CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, email VARCHAR(120) NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, validated BOOLEAN DEFAULT FALSE );


Кийинки бөлүмдө сиз үчүн маалымат базасын суроо үчүн SQLAlchemy'тин ORM структурасы колдонулат. Класс аты сиздин маалымат базасынын таблицанын атына дал келиши керек экенин эске алыңыз, антпесе ката аласыз. db.model колонна атын, анын түрүн, узундугун, ачкычын жана нөл маанисин камтыган стол орнотууларды билдирет:


 class User(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(120), unique=True, nullable=False) created_at = db.Column(db.DateTime, server_default=db.func.now()) validated = db.Column(db.Boolean, default=False)


Эгер сиз MySQL маалымат базасынын таблицасын кол менен түзө элек болсоңуз, аны бул Flask коду менен түздөн-түз class User коду блогунан кийин жасай аласыз:

 # Create the database table with app.app_context(): db.create_all()


Эми биз 2 барак/маршрут (индекс, катталуу), электрондук почта билдирүүсү жана ырастоо болгон арткы кодду киргизебиз. Каттоо бетинде форманы тапшырууга мүмкүндүк берген GET/POST ыкмалары камтылган. bleach объект коопсуздукту камсыз кылуу жана зыяндуу скрипттерди азайтуу үчүн колдонуучудан киргизүүнү тазалаган Python кеңейтүүсү. Андан кийин sserializer текшерүү шилтемесин электрондук почта аркылуу жөнөтүү үчүн бир жолку белгини жаратат.


 @app.route('/') def index(): return '<h1>Index page</h1>' @app.route('/signup', methods=['GET', 'POST']) def signup(): if request.method == 'POST': email = bleach.clean(request.form.get('email')) # Insert user into the database new_user = User(email=email) try: db.session.add(new_user) db.session.commit() except Exception as e: print(f"Error occurred saving to db: {e}") # Send confirmation email token = sserialzer.dumps(email, salt='email-confirm') msg = Message('Confirm your Email', sender='[email protected]', recipients=[email]) link = url_for('confirm_email', token=token, _external=True) msg.body = f'Your link is {link}' try: mail.send(msg) except Exception as e: print(f"Error occurred sending message: {e}") flash("Error occurred sending message!") return render_template('signup.html') flash('A confirmation email has been sent to your email address.', 'success') return redirect(url_for('index')) return render_template('signup.html')


HTML катталуу формасын кошуудан мурун, келгиле, кош кошулуу мүмкүнчүлүгүн текшерүү үчүн маршрутту кошуп, серверди бүтүрөлү. Бул маршрут биз мурда түзүлгөн s өзгөрмөсүн колдонот, ал убакытты сезгич, жашыруун белгини жаратат. Караңыз чоо-жайы үчүн документтер .


Максималдуу жаш - бул шилтеменин мөөнөтү аяктаганга чейин секундалар, ошондуктан бул учурда колдонуучуга электрондук почта дарегин ырастоо үчүн 20 мүнөт бар.


 @app.route('/confirm_email/<token>') def confirm_email(token): try: email = sserialzer.loads(token, salt='email-confirm', max_age=1200) # Token expires after 1 hour except SignatureExpired: return '<h1>The token is expired!</h1>' # Update field in database user = User.query.filter_by(email=email).first_or_404() user.validated = True db.session.commit() return '<h1>Email address confirmed!</h1>'


Эми, эгер файл түздөн-түз аткарылса (импорттолгон модулдан айырмаланып), Python скриптти аткарууну айткан бардык жердеги негизги билдирүү үчүн:

 if __name__ == '__main__': app.run()


Бул арткы кодду аягына чыгарардан мурун, колдонуучунун киргизүүсү үчүн бизге дагы эле алдыңкы HTML керек. Биз муну Фласктын орнотулган Jinja шаблоны менен жасайбыз. templates/signup.html деп аталган файлды түзүңүз, анын аталышы app.py ичинде мурда түзгөн маршрутуңузга дал келиши керек. Демейки боюнча, Jinja html файлдары үчүн каталогду /templates колдонот. Сиз бул жөндөөнү өзгөртө аласыз, бирок бул окуу куралы үчүн биз колдонмонун /templates каталогун колдонобуз.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Email Sign Up</title> </head> <body> <h1>Sign Up</h1> <form action="{{ url_for('signup') }}" method="POST"> <input type="email" name="email" placeholder="Enter your email" required> <input type="submit" value="Sign Up"> </form> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} <ul> {% for category, message in messages %} <li>{{ message }}</li> {% endfor %} </ul> {% endif %} {% endwith %} </body> </html>


Мүчүлүштүктөрдү оңдоо иштетилген менен flask буйругун иштеткенде, кодуңуз ушул учурдан баштап иштеши керек. Бул буйрук сабында, ошондой эле браузер терезесинде каталарды көрүүгө мүмкүндүк берет:


 flask --app app.py --debug run


Браузериңизди буйрук сабында (localhost) көрсөтүлгөн доменге ачыңыз жана индекс барагы көрсөтүлүшү керек. Текшерүү шилтемесин алуу үчүн форманы жарактуу электрондук почта дарегин колдонуп тапшырууга аракет кылыңыз. Шилтемени алгандан кийин, ал http://localhost:5000/confirm_email/InRvbUByYXRldG91cmd1aWRlcy5jb20i.ZteEvQ.7o1_L0uM9Wl8uii7KhJdiWAH сыяктуу көрүнүшү керек, сиз аны ээрчип, бул жерде көрсөтүлгөн электрондук почтанын дарегин туура көрсөтсөңүз болот:


 @app.route('/confirm_email/<token>') def confirm_email(token): try: email = sserializer.loads(token, salt='email-confirm', max_age=1200) # Token expires after 1 hour except SignatureExpired: return '<h1>Oops, the token expired!</h1>' # Update field in database user = Users.query.filter_by(email=email).first_or_404() user.validated = True try: db.session.commit() except Exception as e: print(f"Error occurred saving to db: {e}") return '<h1>Email address confirmed!</h1>'


Бул маршрут сизге мурда жөнөтүлгөн токен сапты кабыл алат жана анын тиешелүү маалымат базасынын жазуусу менен дал келгенин текшерет. Эгер ошондой болсо, ал validated талааны True кылып жаңылайт жана сиз катталуу формаңыздан баш тартпагандыгын билип эс алсаңыз болот.


Бул бардык ийгиликтүү ишканалар каттоо тутумдарында колдонгон маанилүү кадам жана азыр сизде да бар. Бирок күтө туруңуз, эгер биз боттук чабуулдарды кокус электрондук почта даректерин текшербестен тапшырып алсакчы? Андан кийин пайдасыз жазуулар менен толтурулган кир маалымат базасы болот. Мунун алдын алалы!


Бот чабуулдарынын алдын алуу же жок дегенде өркүндөтүлгөндөрдү азайтуу үчүн, сиз өзүңүздүн убакытты талап кылган чечимиңизди, анын ичинде Redis сыяктуу эстутумдагы маалымат базасын талап кылган IP чектөөчүсүн түзө аласыз же Google'дун captcha же үчүнчү тараптын кызматын колдоно аласыз. hCaptcha.


Биздин окуу куралыбызда биз кошумчалайбыз hcaptcha акысыз планы . Бул жазуу учурунда, Google'дун captcha'сы бекер эмес жана hcaptcha. Бул сиздин сайтта иштеши үчүн, алар менен катталып, API ачкычын captchaдан алышыңыз керек.


Бизге жаңы талаптар керек, ошондуктан аларды орнотуңуз:
pip install flask-hcaptcha requests


Сурамдар текшерүү үчүн hcaptcha электрондук почта дарегин жөнөтүү үчүн керек. Ачкычты алыңыз жана hcaptchaнын JavaScript файлын HTML катталуу формасы менен бириктириңиз. Файлды HTML баракчаңыздын башына жана формаңызга сайт ачкычыңызды кошуңуз:


 <head> ... <script src="https://hcaptcha.com/1/api.js" async defer></script> </head> <body> ... <form action="{{ url_for('signup') }}" method="POST"> <input type="email" name="email" placeholder="Enter your email" required> <input type="submit" value="Sign Up"> <div class="h-captcha" data-sitekey="b62gbcc-5cg2-41b2-cd5a-de95dd1eg61h" data-size="compact"></div> </form>


Бул коддогу сайттын ачкычы мисал; акысыз пландан өзүңүздүн планыңыз керек болот. Бул сайт ачкычы формаңызды текшерет жана hcaptcha тарабынан белгилүү болгон спам-боттордун толук тизмеси менен сайтка келген адамды текшерет.


Андан кийин, hcaptchaнын жашыруун ачкычын (сайттын ачкычы эмес) app.config объектисине кошуу үчүн app.py файлыңызды өзгөртүңүз жана аны өз маалымат базасына сактоодон мурун hcaptchaга жооп жөнөтүңүз.


 app.config['HCAPTCHA_SECRET_KEY'] = 'your-secret-hcaptcha-key' ... @app.route("/signup", methods=['GET', 'POST']) def signup(): if request.method == 'POST': email = bleach.clean(request.form.get('email')) hcaptcha_response = request.form.get('h-captcha-response') # Verify hCaptcha response payload = { 'secret': app.config['HCAPTCHA_SECRET_KEY'], 'response': hcaptcha_response } try: response = requests.post('https://hcaptcha.com/siteverify', data=payload, timeout=10) result = response.json() except requests.exceptions.RequestException as e: print(f"Request failed: {e}") if not result.get('success'): flash('CAPTCHA validation failed, please try again.', 'danger') ... # Insert user into the database new_user = Users(email=email)


Бул аткарылгандан кийин, сиздин катталуу формаңызда hcaptcha сөлөкөтү көрсөтүлөт жана ал спамдын алдын алуу үчүн иштетилиши керек. Эми сизде жаңы колдонмоңуз үчүн бекем формаңыз бар.


Эгер кандайдыр бир катага туш болсоңуз же кодуңузда ката бар болсо, толтурулган кодду текшере аласыз менин github.com


Көбүрөөк кааласаңыз комментарий калтырыңыз.