Flask-Mailによるメール送信
設定ファイル config.py:
# メール設定
MAIL_HOST = "smtp.qq.com"
MAIL_PORT = 465
MAIL_TLS = False
MAIL_SSL = True
MAIL_DEBUG = True
MAIL_ACCOUNT = "your@qq.com"
MAIL_AUTH_CODE = "authorization_code"
MAIL_SENDER = "your@qq.com"
メール送信ハンドラ user_controller.py:
@user_bp.route("/send-testmail")
def send_test_email():
msg = EmailMessage(
title="テストメール",
receivers=['recipient@example.com'],
content="これはテストメールです"
)
email_client.send(msg)
return "メール送信成功"
拡張機能初期化 exts.py:
from flask_mail import Mail
email_client = Mail()
アプリケーション統合 app.py:
from exts import email_client
email_client.init_app(application)
ユーザー登録機能
フォーム検証 forms.py:
from wtforms import Form, StringField, validators
from models import VerificationModel, UserProfile
class SignupForm(Form):
user_name = StringField(validators=[validators.Length(min=3, max=20)])
email_addr = StringField(validators=[validators.Email()])
verification_code = StringField(validators=[validators.Length(min=4, max=4)])
passphrase = StringField(validators=[validators.Length(min=6, max=20)])
passphrase_confirm = StringField(validators=[validators.EqualTo("passphrase")])
def validate_verification(self, field):
code_input = field.data
email = self.email_addr.data
verification_record = VerificationModel.fetch_by_email(email)
if not verification_record or verification_record.code.lower() != code_input.lower():
raise validators.ValidationError("認証コードが不正です")
def validate_email_addr(self, field):
email = field.data
if UserProfile.email_exists(email):
raise validators.ValidationError("メールアドレスは既に登録されています")
ユーザーコントローラ user_controller.py:
from datetime import datetime
from flask import render_template, request, redirect, jsonify
from werkzeug.security import generate_password_hash
from .forms import SignupForm
@user_bp.route("/signup", methods=['GET', 'POST'])
def signup():
if request.method == 'GET':
return render_template("signup.html")
else:
form_data = SignupForm(request.form)
if form_data.validate():
new_user = UserProfile(
email=form_data.email_addr.data,
username=form_data.user_name.data,
password=generate_password_hash(form_data.passphrase.data)
)
db_session.add(new_user)
db_session.commit()
return redirect(url_for("user.login"))
return redirect(url_for("user.signup"))
@user_bp.route("/request-code", methods=['POST'])
def send_verification():
email_addr = request.form.get("email")
if not email_addr:
return jsonify({"status": 400, "message": "メールアドレスが必要です"})
charset = string.ascii_letters + string.digits
new_code = ''.join(random.choices(charset, k=4))
verification_msg = EmailMessage(
title="認証コード通知",
receivers=[email_addr],
content=f"【フォーラム認証】認証コード: {new_code} (有効期限10分)"
)
email_client.send(verification_msg)
VerificationModel.update_or_create(email_addr, new_code)
return jsonify({"status": 200})
データモデル models.py:
class UserProfile(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(200), nullable=False)
email = db.Column(db.String(100), nullable=False, unique=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
class VerificationModel(db.Model):
__tablename__ = "email_verifications"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
email = db.Column(db.String(100), nullable=False)
code = db.Column(db.String(4), nullable=False)
generated_at = db.Column(db.DateTime, default=datetime.utcnow)