Vonage×Pythonで2要素認証アプリを爆速で作る

## はじめに
VonageのコミュニケーションAPIは、SMS、音声、ビデオ、二要素認証をアプリケーションに簡単に組み込むことができるサービスです。

今回は**PythonでVonageを使って2要素認証のアプリ**を簡単に作ってみました。


記事では、Vonageを使用するための基本的なセットアップから始め、実際に2要素認証を行うためのプロググラムを解説します。特に、環境設定、APIキーの取得、そしてStreamlitを使ったシンプルなウェブアプリケーションの構築に焦点を当てています。

この記事が、自分自身のアプリケーションやサービスに2要素認証を組み込む際の参考になれば幸いです。

## 基礎:Vonageの使い方
### 事前準備:APIキーとシークレットキーの取得
Vonageのアカウントを作成して、ログインしてください。

https://www.vonagebusiness.jp/log-in/#api

筆者は無料プランでアカウントを作成しました。無料プランだと2ユーロの無料クレジットがもらえます、以下がログイン時の画像です。
以降必要なので、APIキーとシークレットキーをメモしてください。(添付画像では隠している箇所です。)

![ 2023-12-16 23.57.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/96e33256-ca83-372c-dd3f-97a2ca611aeb.png)



### 事前準備:環境変数とライブラリのインストール

環境変数にAPIキーとシークレットキーを設定します。

```bash 
% export VONAGE_API_KEY={APIキー}
% export VONAGE_SECRET_KEY={シークレットキー}
```

Vonage用のライブラリ`vonage`をインストールします。
```bash 
（仮想環境）% pip install vonage
```


### Vonageクライアントとの接続と2要素認証のためのクラス定義
```python 
import os
import vonage

vonage_api_key = os.getenv("VONAGE_API_KEY")
vonage_secret_key = os.getenv("VONAGE_SECRET_KEY")

client = vonage.Client(key=vonage_api_key, secret=vonage_secret_key)
verify = vonage.Verify(client)
```

### 認証コード送信
```python 
response = verify.start_verification(number={電話番号}, brand="AcmeInc")

if response["status"] == "0":
    print("Started verification request_id is %s" % (response["request_id"]))
    request_id　= response["request_id"]
else:
    print("Error: %s" % response["error_text"])
```

### 2要素認証
```python 
response = verify.check(request_id, code={PIN番号})

if response["status"] == "0":
    print("Verification successful, event_id is %s" % (response["event_id"]))
else:
    print("Error: %s" % response["error_text"])
```

PIN番号は携帯に送られるものです。

### 2要素認証のキャンセル
一定時間経過した後に、2要素認証のリクエストをキャンセルする場合は以下のように記述します。

```python 
response = verify.cancel(request_id)

if response["status"] == "0":
    print("Cancellation successful")
else:
    print("Error: %s" % response["error_text"])

```

## 実践:Vonageを用いた2要素認証アプリ
streamlitで2要素認証アプリを作ってみます。

```python 
（仮想環境）% pip install streamlit
```

実際の2要素認証アプリのコードはこちらです。


```python app.py
import os
import streamlit as st
import vonage

# 環境変数からVonageの認証情報を取得
vonage_api_key = os.getenv("VONAGE_API_KEY")
vonage_secret_key = os.getenv("VONAGE_SECRET_KEY")

# Vonageクライアントの初期化
client = vonage.Client(key=vonage_api_key, secret=vonage_secret_key)
verify = vonage.Verify(client)

# タイトル
st.title("2要素認証テスト")

# 電話番号を入力するフォーム
phone_number = st.text_input("電話番号を入力してください")

# 状態の初期化
if 'request_id' not in st.session_state:
    st.session_state['request_id'] = None
if 'send_verification' not in st.session_state:
    st.session_state['send_verification'] = False
if 'verification_success' not in st.session_state:
    st.session_state['verification_success'] = False

# 2要素認証を行うためのボタン
if st.button("認証コードを送信"):
    response = verify.start_verification(number=phone_number, brand="AcmeInc")
    if response["status"] == "0":
        st.session_state['request_id'] = response["request_id"]
        st.session_state['send_verification'] = True
    else:
        st.error("エラー: %s" % response["error_text"])

# PINコードを入力するフォームと送信ボタン
if st.session_state['request_id']:
    pin_code = st.text_input("PINコードを入力してください")
    if st.button("PINコードを送信"):
        response = verify.check(st.session_state['request_id'], code=pin_code)
        if response["status"] == "0":
            st.session_state['verification_success'] = True
        else:
            st.error("エラー: %s" % response["error_text"])

# メッセージの表示
if st.session_state['send_verification']:
    st.success("認証コードを送信に成功しました。")
if st.session_state['verification_success']:
    st.success("2要素認証に成功しました。")
```

アプリは以下で実行できます。

```bash 
% streamlit run app.py
```

アプリはこんな感じです。(フォームに入力した電話番号&PINコードは削除しています、)

電話番号を入力して、認証コードを送信ボタンを押すと、電話番号に4桁のPINコードが送信されます。

PINコードを入力して、PINコードを送信ボタンを押すと、2要素認証がVonage側で行われ、成功したらメッセージが出ます。

![ 2023-12-17 0.06.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/57b63d69-05d1-4fc1-ed25-7317a60d345f.png)





ちなみにSMS使用時のコストは、「アナリティクス->SMS分析」から簡単に確認できます。

![ 2023-12-16 17.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/9a2071c5-e7b9-54b7-74d8-0e43b755bab5.png)

## おわりに
Vonageは予想以上に使いやすかったです。

Vonageは他にも音声やビデオ通話のAPIが公開されています。(というかこっちがメインな気がしますが)

ドキュメントもわかりやすいので、機会があれば試してみたいと思います。