-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
!
-
|
!
-
!
| import sys
import os
import urllib.parse
import secrets
import smtplib
from email.mime.text import MIMEText
import sqlite3
from datetime import datetime, timedelta
def generate_otp():
return f"{secrets.randbelow(1000000):06d}"
def send_email(to_email, otp_code):
smtp_server = "smtp.lolipop.jp"
smtp_port = 465
smtp_user = "sample@21gata.com"
smtp_password = "sample-password"
msg = MIMEText(f"メールアドレス登録の認証コードは {otp_code} です。\n有効期限は10分間です。")
msg["Subject"] = "【仮登録】認証コードのお知らせ"
msg["From"] = smtp_user
msg["To"] = to_email
try:
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(smtp_user, smtp_password)
server.send_message(msg)
server.quit()
except Exception as e:
pass
def init_db():
conn = sqlite3.connect('auth.db')
cursor = conn.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS users (email TEXT PRIMARY KEY)')
cursor.execute('CREATE TABLE IF NOT EXISTS temp_registrations (email TEXT PRIMARY KEY, code TEXT, expires_at TIMESTAMP)')
conn.commit()
return conn
def main():
print("Content-Type: text/html; charset=utf-8")
print()
content_length = int(os.environ.get('CONTENT_LENGTH', 0))
post_data = sys.stdin.read(content_length)
form = urllib.parse.parse_qs(post_data)
action = form.get('action', [''])[0]
email = form.get('email', [''])[0]
conn = init_db()
cursor = conn.cursor()
if action == 'send_otp' and email:
cursor.execute('SELECT email FROM users WHERE email = ?', (email,))
if cursor.fetchone():
print("<p style='color:red;'>このメールアドレスは既に登録されています。</p>")
print('<p><a href="login.cgi">ログイン画面へ</a></p>')
return
otp_code = generate_otp()
expires_at = datetime.now() + timedelta(minutes=10)
cursor.execute('DELETE FROM temp_registrations WHERE email = ?', (email,))
cursor.execute('INSERT INTO temp_registrations (email, code, expires_at) VALUES (?, ?, ?)',
(email, otp_code, expires_at))
conn.commit()
send_email(email, otp_code)
print(f"""
<h2>新規登録 - 認証コード入力</h2>
<p>確認のため、{email} 宛に6桁の認証コードを送信しました。</p>
<form method="POST" action="register.cgi">
<input type="hidden" name="action" value="verify_and_register">
<input type="hidden" name="email" value="{email}">
<input type="text" name="otp_code" pattern="[0-9]{{6}}" placeholder="123456" required>
<button type="submit">登録を確定する</button>
</form>
""")
return
elif action == 'verify_and_register' and email:
input_code = form.get('otp_code', [''])[0]
cursor.execute('SELECT code, expires_at FROM temp_registrations WHERE email = ?', (email,))
row = cursor.fetchone()
if row:
stored_code, expires_at_str = row
expires_at = datetime.fromisoformat(expires_at_str)
if input_code == stored_code and datetime.now() <= expires_at:
try:
cursor.execute('INSERT INTO users (email) VALUES (?)', (email,))
cursor.execute('DELETE FROM temp_registrations WHERE email = ?', (email,))
conn.commit()
print("<h2>登録が完了しました!</h2>")
print('<p><a href="login.cgi">ログイン画面へ進む</a></p>')
return
except sqlite3.IntegrityError:
print("<p style='color:red;'>エラー: 既に登録されています。</p>")
else:
print("<p style='color:red;'>コードが間違っているか、有効期限が切れています。</p>")
else:
print("<p style='color:red;'>登録の要求が見つかりません。最初からやり直してください。</p>")
print("""
<h2>新規ユーザー登録</h2>
<form method="POST" action="register.cgi">
<input type="hidden" name="action" value="send_otp">
<input type="email" name="email" placeholder="メールアドレスを入力" required>
<button type="submit">認証コードを送信</button>
</form>
""")
if __name__ == "__main__":
main()
|