API の /api/v1/getcode アプリの URL パスは、英数字コードとタイムスタンプを含む JSON 応答を生成します。
まず、@app.route
デコレーターは、get_code
関数が /api/v1/getcode URL への要求を処理することを Flask に通知します。
@app.route('/api/v1/getcode', methods=['GET'])
def get_code():
次に、アプリはサード パーティ製の API を呼び出します。URL は number_url
にあり、ヘッダーのキー コンテナーから取得するアクセス キーを提供します。
headers = {
'Content-Type': 'application/json',
'x-functions-key': access_key
}
r = requests.get(url = number_url, headers = headers)
if (r.status_code != 200):
return "Could not get you a code.", r.status_code
サード パーティ製 API の例は、Azure Functions のサーバーレス環境にデプロイされます。 ヘッダーの x-functions-key
プロパティは、Azure Functions がヘッダーにアクセス キーを表示する方法です。 詳細については、「Azure Functions HTTP トリガーの - 承認キーの」を参照してください。 何らかの理由で API の呼び出しが失敗した場合、エラー メッセージと状態コードが返されます。
API 呼び出しが成功し、数値が返されると仮定すると、アプリはその数値とランダムな文字 (独自の random_char
関数を使用) を使用して、より複雑なコードを構築します。
data = r.json()
chars1 = random_char(3)
chars2 = random_char(3)
code_value = f"{chars1}-{data['value']}-{chars2}"
code = { "code": code_value, "timestamp" : str(datetime.utcnow()) }
ここで code
変数には、コード値とタイムスタンプを含む、アプリの API の完全な JSON 応答が含まれています。 応答の例は {"code":"ojE-161-pTv","timestamp":"2020-04-15 16:54:48.816549"}
です。
ただし、その応答を返す前に、Queue クライアントの send_message
メソッドを使用して、ストレージ キューにメッセージを書き込みます。
queue_client.send_message(code)
return jsonify(code)
キュー メッセージの処理
キューに格納されているメッセージは、 Azure portal、Azure CLI コマンド az storage message get
、または Azure Storage Explorer を使用して表示および管理できます。 サンプル リポジトリには、アプリ エンドポイントからコードを要求し、メッセージ キューを確認するためのスクリプト (test.cmd と test.sh) が含まれています。
az storage message clear
コマンドを使用してキューをクリアするスクリプトもあります。
通常、この例のようなアプリには、キューからメッセージを非同期的にプルして処理を進める別のプロセスがあります。 前述のように、この API エンドポイントによって生成される応答は、2 要素ユーザー認証を使用してアプリ内の別の場所で使用される場合があります。 その場合、アプリは一定期間 (たとえば 10 分) 後にコードを無効にする必要があります。 このタスクを実行する簡単な方法は、有効な 2 要素認証コードのテーブルを維持することです。このコードは、ユーザーのサインイン手順で使用されます。 その後、アプリには、次のロジック (擬似コード) を使用した単純なキュー監視プロセスが含まれます。
pull a message from the queue and retrieve the code.
if (code is already in the table):
remove the code from the table, thereby invalidating it
else:
add the code to the table, making it valid
call queue_client.send_message(code, visibility_timeout=600)
この擬似コードは、メッセージがキューに表示されるまでの秒数を指定する、send_message
メソッドの省略可能な visibility_timeout
パラメーターを使用します。 既定のタイムアウトは 0 であるため、API エンドポイントによって最初に書き込まれたメッセージは、キュー監視プロセスにすぐに表示されます。 その結果、そのプロセスは、それらをすぐに有効なコード テーブルに格納します。 プロセスはタイムアウトで同じメッセージをもう一度キューに入れ、10 分後にコードを再び受信します。この時点でテーブルから削除されます。
Azure Functions でのメイン アプリ API エンドポイントの実装
この記事で前に示したコードでは、Flask Web フレームワークを使用して API エンドポイントを作成します。 Flask は Web サーバーで実行する必要があるため、このようなコードは Azure App Service または仮想マシンにデプロイする必要があります。
代替デプロイ オプションは、Azure Functions のサーバーレス環境です。 この場合、すべてのスタートアップ コードと API エンドポイント コードは、HTTP トリガーにバインドされているのと同じ関数内に含まれます。 App Service と同様に、関数アプリケーション設定 を使用して、コードの環境変数を作成します。
実装の 1 つが簡単になるのは、Queue Storage を使用した認証です。 キューの URL と資格情報オブジェクトを使用して QueueClient
オブジェクトを取得する代わりに、関数の キュー ストレージ バインド を作成します。 バインドは、バックグラウンドですべての認証を処理します。 このようなバインディングを使用すると、関数には、すぐに使用できるクライアント オブジェクトがパラメーターとして指定されます。 詳細とコード例については、「Azure Functions を Azure Queue Storageに接続する」を参照してください。
次の手順
このチュートリアルでは、アプリがマネージド ID を使用して他の Azure サービスと認証する方法と、アプリが Azure Key Vault を使用してサードパーティ API に必要な他のシークレットを格納する方法について説明しました。
Azure Key Vault と Azure Storage でここで示したのと同じパターンが、他のすべての Azure サービスに適用されます。 重要な手順は、Azure portal 上のサービスのページ内または Azure CLI を使用して、アプリに適切なロールを割り当てることです。 (「Azure ロールを割り当てる方法」を参照してください)。 サービスのドキュメントを確認して、他のアクセス ポリシーを構成する必要があるかどうかを確認してください。
ローカル開発に使用しているサービス プリンシパルに同じロールとアクセス ポリシーを割り当てる必要があることを忘れないでください。
つまり、このチュートリアルを完了すると、任意の数の他の Azure サービスと任意の数の他の外部サービスに知識を適用できます。
このチュートリアルで触れていない 1 つの主題は、ユーザーの認証です。 Web アプリのこの領域を調べるには、「Azure App Serviceでユーザーをエンド ツー エンドで認証および承認する」から始めます。
関連項目
- Azure で Python アプリを認証および承認する方法
- チュートリアル サンプル: github.com/Azure-Samples/python-integrated-authentication
- Microsoft Entra のドキュメント
- Azure Key Vault のドキュメント