[login認証 Outlook ]   mail ワンタイムcode入力. → 入力確認 → OK : ログイン

# startは、これだ！

→ page　見つからず　検索中

# 続き

```riby:
Azureでアプリ登録
https://portal.azure.com → 「アプリの登録」
リダイレクトURI：http://localhost:5000/login/microsoft/authorized
クライアントID・シークレットをメモ
モデルに、microsoft_id：Microsoft OAuth から取得一意ID（subやid）add
```

```php:いるもん
pip install flask flask-dance flask-session flask-mail flask-oauthlib
```

## init.py

```php:
import os
from flask import Flask
from flask_migrate import Migrate
from pathlib import Path
from .extensions import db, bcrypt, login_manager
from .models import User, Profile
from .routes import main as auth_blueprint
from flask_session import Session
from flask_mail import Mail
from flask_dance.contrib.microsoft import make_microsoft_blueprint

BASE_DIR = Path(__file__).resolve().parent

UPLOAD_FOLDER = os.path.join(BASE_DIR, 'uploads')
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

login_manager.login_view = 'main.login'
login_manager.login_message = "ログインしてください"

def create_app(test_config=None):
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'your-secret-key'  # 本番は環境変数推奨
    app.config['SESSION_TYPE'] = 'filesystem'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024  # 1MB

    # Microsoft OAuth 設定
    ms_bp = make_microsoft_blueprint(
        client_id="あなたのクライアントID",
        client_secret="あなたのクライアントシークレット",
        scope=["User.Read"],
        redirect_url="/login/microsoft/authorized"
    )
    app.register_blueprint(ms_bp, url_prefix="/login")

    # メール設定（例：Gmail）
    app.config['MAIL_SERVER'] = 'smtp.gmail.com'
    app.config['MAIL_PORT'] = 587
    app.config['MAIL_USE_TLS'] = True
    app.config['MAIL_USERNAME'] = 'あなたのメール'
    app.config['MAIL_PASSWORD'] = 'アプリパスワード'
    mail = Mail(app)

    # セッションと拡張機能初期化
    Session(app)
    db.init_app(app)
    bcrypt.init_app(app)
    login_manager.init_app(app)
    Migrate(app, db)

    app.register_blueprint(auth_blueprint)

    if test_config:
        app.config.from_mapping(test_config)

    return app
```

# ログイン＋コード送信

```php:index.py
@app.route("/")
def index():
    if not microsoft.authorized:
        return redirect(url_for("microsoft.login"))

    resp = microsoft.get("/v1.0/me")
    email = resp.json().get("mail") or resp.json().get("userPrincipalName")
    session['email'] = email

    # ワンタイムコード生成
    code = str(random.randint(100000, 999999))
    session['auth_code'] = code

    # メール送信
    msg = Message('ログイン認証コード', recipients=[email])
    msg.body = f'あなたの認証コードは {code} です。'
    mail.send(msg)

    return redirect("/verify")
```

# モデルにmicrosoft_id　追加

```ruby:
from .extensions import db
from flask_login import UserMixin

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(150), nullable=False)
    email = db.Column(db.String(150), unique=True, nullable=False)
    password = db.Column(db.String(256)) 
    microsoft_id = db.Column(db.String(100), unique=True)  
    access_token = db.Column(db.String(255))  # Microsoft OAuthのアクセストークン
  profile = db.relationship('Profile', backref='user', uselist=False)


class Profile(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    bio = db.Column(db.Text)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
```

# 認証コード入力 ＋確認処理

```php:
@app.route("/verify", methods=["GET", "POST"])
def verify():
    if request.method == "POST":
        input_code = request.form["code"]
        if input_code == session.get("auth_code"):
            return "ログイン成功！ようこそ " + session["email"]
        else:
            return "コード間違い。"

    return render_template_string('''
        <form method="post">
            認証コード：<input name="code">
            <input type="submit" value="確認">
        </form>
    ''')
```

# Tokenつき版 

```php:
import os
from flask import Flask, redirect, url_for, session
from flask_oauthlib.client import OAuth
from flask_mail import Mail, Message

app = Flask(__name__)
app.secret_key = os.urandom(24)

# Microsoft OAuth設定
oauth = OAuth(app)
microsoft = oauth.remote_app(
    'microsoft',
    consumer_key='あなたのクライアントID',
    consumer_secret='あなたのクライアントシークレット',
    request_token_params={
        'scope': 'wl.basic wl.emails',
    },
    base_url='https://graph.microsoft.com/v1.0/',
    request_token_url=None,
    access_token_method='POST',
    access_token_url='https://login.microsoftonline.com/common/oauth2/v2.0/token',
    authorize_url='https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
)

# メール設定（Outlook）
app.config['MAIL_SERVER'] = 'smtp-mail.outlook.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'あなたのメールアドレス'
app.config['MAIL_PASSWORD'] = 'アプリパスワード'
mail = Mail(app)

@app.route('/')
def index():
    return 'Welcome to the Microsoft OAuth integration!'

@app.route('/login')
def login():
    return microsoft.authorize(callback=url_for('authorized', _external=True))

@app.route('/login/authorized')
def authorized():
    response = microsoft.authorized_response()
    if response is None or response.get('access_token') is None:
        return 'Access denied: reason={} error={}'.format(request.args['error_reason'], request.args['error_description'])

    session['oauth_token'] = (response['access_token'], '')
    
    # アクセストークンを使ってOutlookからメールを送信
    send_email()

    return 'Login successful and email sent!'

def send_email():
    msg = Message(
        'Hello from Flask',
        sender='あなたのメールアドレス',
        recipients=['宛先メールアドレス']
    )
    msg.body = 'This is a test email sent from Flask using Outlook.'
    mail.send(msg)

@microsoft.tokengetter
def get_microsoft_oauth_token():
    return session.get('oauth_token')

if __name__ == '__main__':
    app.run(debug=True)
```
<br>

＃ 解説　見まとめ

```php:
outlookのメール機能もつけたい : トークン必要性　大

microsoftというOAuthの設定で、Microsoftの認証を行います。consumer_keyとconsumer_secretを適切に設定してください。

send_email()関数でOutlookを通じてメールを送信します。この部分では、OutlookのSMTPサーバーを使ってメールを送信しています。

/login/authorizedでアクセストークンを取得し、そのトークンを使ってOutlookメールを送信します。
```


あと　ChatGPT

https://chatgpt.com/c/6821706b-e238-8010-a1fd-0c662eb50b35