Functions: APIゲートウェイを使用したAPIキーの検証
このチュートリアルでは、Oracle Functionsを使用して、Oracle API Gatewayから渡されるAPIキーを検証します。APIキーは、クライアントに特定のトークンを渡すように要求することでAPIを保護するための単純な方法です。ゲートウェイは、トークンをカスタム認可プロバイダとして使用して、リクエストを検証できます。トークンを検証し、認証されたJSONレスポンスを返すPythonファンクションを作成します。
主なタスクは:
- 必要な情報を収集します。
- ファンクションのアプリケーションを作成します。
- 「Hello World!」ファンクションを作成します。
- APIキーを検証するようにファンクションを変換します。
- ファンクションをデプロイおよびテストします。
- ファンクションのAPIゲートウェイを作成します
- APIゲートウェイを使用して、インターネットからファンクションをコールします。

その他の情報については、次のWebサイトを参照してください。
開始する前に
このチュートリアルを正常に実行するには、次が必要です:
- 有料Oracle Cloud Infrastructureアカウント。Oracle Cloud Infrastructureへのサインアップを参照してください。
- Oracle Functions開発をサポートするように構成されたOCIアカウント。クラウド・シェルでのOracle Functionsのクイックスタートを参照してください。
- Oracle Functionsの2つの概要チュートリアルのいずれかを完了します。
- 2つのチュートリアルのいずれかを完了すると、次のようになります:
- Oracle Functionsは、アプリケーションを作成してファンクションをデプロイするために設定および構成されます。
- Oracle Registryは、ファンクション・イメージを格納するように設定されます。
- DockerはOracle Registryにログインしています。
- Oracle Functionsに必要なVCNおよび必要なリソース。
- APIキー・ペアおよび認証トークン。
Oracle CLI
- Python 3.6以上およびpip3。
- Dockerエンジン: LinuxコンピュータまたはLinux VM。サポートされているバージョンおよびディストリビューションについては、Dockerエンジンの要件を参照してください。
- Dockerデスクトップ: MacOSまたはWindows 10で使用可能です。
- Windows 10: WSL 2およびUbuntuまたはその他のディストリビューションがインストールされたWindows 10 update 2004。
ノート
Dockerには、Windows 10 update 2004でのWSL 2に対する特別なLinuxサポートが含まれています。 - MacOS: MacOS用Dockerデスクトップのインストールを参照してください。
- Windows 10: WSL 2およびUbuntuまたはその他のディストリビューションがインストールされたWindows 10 update 2004。
Oracle Cloud Shell
- クラウド・シェルを使用する場合、前述のソフトウェアのリストはすでにインストールされています。
1. 必要な情報の収集
チュートリアルを完了するために必要なすべての情報を収集します。次の情報をメモ帳にコピーします。
コンパートメントを作成するには、コンパートメントの作成を参照してください。コンパートメントを作成したら、コンパートメントOCIDとコンパートメント名を保存します。
既存のコンパートメントからコンパートメントOCIDを取得するには:
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「コンパートメント」をクリックします。
- コンパートメントを選択します。
- OCIDフィールドの「コピー」リンクをクリックします。
コンパートメントOCIDとコンパートメント名を保存します。
チュートリアル用に次の情報を書き留めていることを確認してください。
-
コンパートメント名:
<your-compartment-name>
例:
my-compartment
-
コンパートメントID:
<your-compartment-OCID>
例:
ocid1.compartment.oc1.aaaaaaa...
-
VCN名:
<your-vcn-name>
例:
my-vcn
ナビゲーション・メニューを開いて「ネットワーキング」をクリックし、「仮想クラウド・ネットワーク」をクリックします。
-
VCNパブリック・サブネット名:
<Public-Subnet-your-vcn-name>
例:
Public-Subnet-my-vcn
ナビゲーション・メニューを開いて「ネットワーキング」をクリックし、「仮想クラウド・ネットワーク」をクリックします。作成したVCNをクリックします。
2. 必要な構成の実行
チュートリアルに必要な構成をすべて実行します。
アプリケーションを作成するには、次のステップに従います。
- ナビゲーション・メニューを開き、「開発者サービス」をクリックします。「ファンクション」で、「アプリケーション」をクリックします。
- 「コンパートメント」ドロップダウンからコンパートメントを選択します。
- 「アプリケーションの作成」をクリックします。
- フォーム・データを入力します。
- 名前:
<your-app-name>
- VCN:
<your-vcn-name>
- サブネット:
<Public-Subnet-your-vcn-name>
- 名前:
- 「作成」をクリックします。
アプリケーションが作成されます。
- ナビゲーション・メニューを開いて「ネットワーキング」をクリックし、「仮想クラウド・ネットワーク」をクリックします。
- Oracle Functionsアプリケーションに使用したVCNの名前をクリックします。
- 新しいVCNが表示された状態で、「パブリック」サブネット・リンクをクリックします。
パブリック・サブネット情報は、ページの下部にあるセキュリティ・リストとともに表示されます。
- 「デフォルト・セキュリティ・リスト」リンクまたは適切なセキュリティ・リスト・リンクをクリックします。
VCNのデフォルトのイングレス・ルールが表示されます。
- 「イングレス・ルールの追加」をクリックします。
「イングレス・ルールの追加」ダイアログが表示されます。
- イングレス・ルールに次の情報を入力します。すべてのデータを入力したら、「イングレス・ルールの追加」をクリックします
イングレス・ルールを次のように入力します:
- ステートレス:選択
- ソース・タイプ: CIDR
- ソースCIDR: 0.0.0.0/0
- IPプロトコル: TCP
- ソース・ポート範囲: (空白のまま)
- 宛先ポート範囲: 443
- 説明: アプリケーションのVCN
「イングレス・ルールの追加」をクリックすると、パブリック・サブネットへのHTTPS接続が許可されます。
次に、APIゲートウェイによるファンクションの呼出しを許可するポリシーを設定します。
最初に、APIゲートウェイの動的グループを作成します。
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「動的グループ」をクリックします。
- 「動的グループの作成」をクリックします。
- 次の情報を入力して、動的グループを定義します。
- 名前:
<name-for-your-dynamic-group>
- 「一致ルール」で、ルール1:
<the-rule-text>
を使用します
次に、サンプル名と、入力する必要があるルールを示します。
- 名前: api-gtw-func-dynamic-group
- 「一致ルール」で、ルール1:
ALL {resource.type = 'ApiGateway', resource.compartment.id = 'ocid1.compartment.<your-compartment-OCID>'}
を使用します
- 名前:
- 「作成」をクリックします。
ここで、APIゲートウェイのポリシーを作成します。
- ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」をクリックします。「アイデンティティ」で、「ポリシー」をクリックします。
- ポリシーの作成をクリックします。
- ポリシーを定義するには、次の情報を入力します。
- 名前:
<name-for-your-policy>
- 説明:
<description-for policy>
- コンパートメント:
<name-of-functions-compartment>
「ポリシー・ビルダー」セクションで:
- 「手動エディタの表示」をクリックします。
- テキスト・ボックスにポリシーを入力します。次に例を示します:
Allow dynamic-group api-gtw-func-dynamic-group to use functions-family in compartment <your-compartment-name>
ノート
最後のパラメータは、コンパートメントOCIDではなく、コンパートメント名です。
- 名前:
- 「作成」をクリックします。
APIゲートウェイによるFunctionsの使用を許可するポリシーが作成されました。
- ターミナルを開きます。
- ファンクションを格納するディレクトリを作成し、そのディレクトリに移動します。
mkdir my-dir-name cd my-dir-name
- Fnを使用してPythonの「Hello World」ファンクションを作成します。
fn init --runtime python my-func-name
このコマンドは、ファンクションおよび構成ファイルを含む
my-func-name
という名前のディレクトリを作成します。 - そのディレクトリに移動します。
- ファンクションをデプロイします。
fn -v deploy --app your-app-name
Dockerイメージが作成され、OCIRにプッシュされ、最終的にOracle Functionsにデプロイされると、様々なメッセージが表示されます。
- ファンクションを呼び出します。
fn invoke your-app-name my-func-name
戻り値:
{"message": "Hello World"}
- パラメータを指定してファンクションを呼び出します。
echo -n '{"name":"Bob"}' | fn invoke your-app-name my-func-name
戻り値:
{"message": "Hello Bob"}
3. APIゲートウェイの作成
ファンクションをコールするには、APIゲートウェイを作成します。
APIゲートウェイを作成するには:
- ナビゲーション・メニューを開き、「開発者サービス」をクリックします。「API管理」で、「ゲートウェイ」をクリックします。
- 「コンパートメント」ドロップダウンからコンパートメントを選択します。
- 「ゲートウェイの作成」をクリックします
- 次の情報を入力して、APIゲートウェイを定義します。
- 名前:
<your-gateway-name>
- タイプ:
<Public>
- コンパートメント:
<your-compartment-name>
- <your-vcn-name>の仮想クラウド・ネットワーク:
<select-your-vcn>
- <your-compartment-nameのサブネット:
<your-public-subnet-name>
- 名前:
- 「作成」をクリックします。APIゲートウェイが作成されるまで数分間待ちます。
次に、APIゲートウェイのデプロイメントを作成します。
- 画面左側の「リソース」セクションで、「デプロイメント」をクリックします。
- 「デプロイメントの作成」をクリックします。
- デプロイメント・タイプに「最初から」が選択されていることを確認します。
- デプロイメントを定義するには、「基本情報」セクションに入力します。
- 名前:
<your-deployment-name>
- パス接頭辞(例):
/tokens
- コンパートメント:
<your-compartment-name>
- APIリクエスト・ポリシー: デフォルト値を使用します
- APIロギング・ポリシー: 「情報」のデフォルト値を使用します
- 名前:
- 「次へ」をクリックします。「ルート1」が選択された状態で「ルート」ダイアログが表示されます。
- ルートを定義するには、「ルート1」セクションに入力します。
- パス:
<your-route-path>
例:
/val-token
- メソッド:
GET POST
- タイプ: Oracle Functions
- <your-compartment-name>のアプリケーション: 作成したFunctionsアプリケーションを選択します。
- ファンクション名: 構成セクションで作成したファンクションを選択します。
- パス:
- 「次へ」をクリックします。選択内容をまとめた「確認」ダイアログが表示されます。
- 「作成」をクリックします。デプロイメントが作成されます。
- ゲートウェイの「デプロイメント」リンクをクリックします。作成したデプロイメントのベース・エンドポイントをコピーします。
例:
https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/tokens
APIゲートウェイおよびデプロイメントを作成すると、インストールをテストできます。curl
コマンドの単純なスクリプトを作成します。curl
のURLを作成するには、エンドポイントにデプロイメント・パスを追加します。
- スクリプト・ファイル
touch gtw01.sh && chmod 755 gtw01.sh
を作成します - スクリプト・ファイルにcurlコマンドを追加します:
#!/bin/bash curl <your-api-gateway-endpoint>/val-token
- コマンドの戻り値:
{"message":"Hello World"}
APIゲートウェイがボイラー・プレートPythonファンクションに接続されました。次に、HTTPリクエストで渡された情報を表示するようにPythonファンクションを更新します。
4. APIキーを検証するためのファンクションの更新
次に、APIキーを検証するようにボイラー・プレートPythonファンクションを変更します。
ボイラー・プレート・ファンクションを見ると、Pythonファンクションは次のようになります。
import io
import json
import logging
from fdk import response
def handler(ctx, data: io.BytesIO = None):
name = "World"
try:
body = json.loads(data.getvalue())
name = body.get("name")
except (Exception, ValueError) as ex:
logging.getLogger().info('error parsing json payload: ' + str(ex))
logging.getLogger().info("Inside Python Hello World function")
return response.Response(
ctx, response_data=json.dumps(
{"message": "Hello {0}".format(name)}),
headers={"Content-Type": "application/json"}
)
このコードを開始点として使用して、後続の項では、ファンクションを、APIキーを検証してトークンを返すPythonファンクションに変換します。
Oracle Functionsでは、リクエストで使用可能なコンテキストに構成データを格納できます。構成データは、アプリケーションまたはファンクションに格納できます。次のコマンドは、アプリケーション構成にAPIキーを格納します。
fn config app <your-app-name> FN_API_KEY ABCD
「ABCD」文字列は、サンプルのキー値です。
ファンクション構成値の設定の詳細は、Fn Projectのランタイム・コンテキストに関するチュートリアルを参照してください。
まず、必要なパッケージのfunc.py
を更新します。
- 必要なパッケージの検証のために、
func.py
のimport
文を更新します:import io import json import logging import datetime from datetime import timedelta from fdk import response
datetime
パッケージを使用して、返されるトークンの有効期限を設定します。 - 次に、ファンクションの本体を削除します。進捗状況に応じて、
response
メソッドおよび関連するコードが追加されます。import io import json import logging import datetime from datetime import timedelta from fdk import response def handler(ctx, data: io.BytesIO = None):
これで、検証コードを使用してファンクションを更新する準備ができました。
次に、APIキーを検証してレスポンスでトークンを返すコードを追加します。コメント付きのコードを次に示します。
import io
import json
import logging
import datetime
from datetime import timedelta
from fdk import response
def handler(ctx, data: io.BytesIO = None):
auth_token = "invalid"
token = "invalid"
apiKey = "invalid"
expiresAt = (datetime.datetime.utcnow() + timedelta(seconds=60)).replace(tzinfo=datetime.timezone.utc).astimezone().replace(microsecond=0).isoformat()
try:
auth_token = json.loads(data.getvalue())
token = auth_token.get("token")
app_context = dict(ctx.Config())
apiKey = app_context['FN_API_KEY']
if token == apiKey:
return response.Response(
ctx,
status_code=200,
response_data=json.dumps({"active": True, "principal": "foo", "scope": "bar", "clientId": "1234", "expiresAt": expiresAt, "context": {"username": "wally"}})
)
except (Exception, ValueError) as ex:
logging.getLogger().info('error parsing json payload: ' + str(ex))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": "API-key"})
)
handler
ファンクションは、ctx
およびdata
パラメータを介して、現在のリクエストに関するシステム情報を受け取ります。- このファンクションは、アプリケーション構成で
FN_API_KEY
が設定されていることを前提としています。次に、このファンクションは、構成値をcurl
POSTリクエスト(-d '{"token":"ABCD"}'
)から送信されたトークン値と比較します。 - 値が一致する場合、検証JSONメッセージが返されます。一致しない場合、401コードがJSONエラー・データとともに返されます。
ファンクション・コードが完成しました。これで、ファンクションをテストする準備が整いました。
- 更新されたファンクションを再デプロイします。
- ファンクションを呼び出して、ファンクションが機能していることを確認します。
POST
データをスクリプトに渡すようにgtw01.sh
スクリプトを更新します。/bin/bash curl -X POST -d '{"token":"ABCD"}' https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/tokens/val-token
- スクリプト
gtw01.sh | jq
を実行します - APIキーが一致する場合、スクリプトからの出力は次のようになります:
{ "active": true, "principal": "foo", "scope": "bar", "clientId": "1234", "expiresAt": "2020-12-16T22:48:50+00:00", "context": { "username": "wally" } }
APIキーが一致しない場合、エラー・メッセージが返されます。
{ "active": false, "wwwAuthenticate": "API-key" }
Oracleファンクションのサンプル・サイトからファンクションの完全なソース・コードをダウンロードできます。
完了しました。ボイラー・プレートPythonファンクションが、APIキーを検証する新しいファンクションに変換されました。このファンクションは、データをAPIゲートウェイに渡し、ファンクションで処理する方法を示します。
次の手順
APIゲートウェイが正常に作成され、そこからファンクションがコールされました。APIキーを検証するようにファンクションが更新されました。
Oracle製品を使用した開発の詳細を確認するには、次のサイトを参照してください: