【技術ブログ】OCI Object StorageとAPI Gatewayを使用して静的サイトを作成してみた

Webサイトをサーバレスで作成時OCI Object Storage、Oracle API Gatewayを使用して、コンパイル済JavaScript Webアプリケーションの静的ホスティングの構成を確認したため下記に記載します。
・ インターネットに接続できるパブリックサブネットが作成されていること
・ セキュリティリストで443ポートが許可されていること
1.Webサイト用コード作成
動作テスト用のコードを作成する。以下のコードはログイン時に認証が成功すると「ログイン成功!」と表示される構成となっている。
【index.html】
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ログインページ</title>
</head>
<body>
<h1>ログイン</h1>
<form id="loginForm">
<label for="username">ユーザー名:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">パスワード:</label>
<input type="password" id="password" name="password" required>
<br><br>
<button type="submit">ログイン</button>
</form>
<p id="message"></p>
<script src="/assets/script.js"></script>
</body>
</html>
【script.js】
document.getElementById('loginForm').addEventListener('submit', function(event) {
event.preventDefault(); // フォームのデフォルト送信を防止
// 仮のユーザー名とパスワード
const validUsername = 'testuser';
const validPassword = 'password123';
// 入力されたユーザー名とパスワードを取得
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
// ログインの判定
if (username === validUsername && password === validPassword) {
document.getElementById('message').innerText = 'ログイン成功!';
document.getElementById('message').style.color = 'green';
} else {
document.getElementById('message').innerText = 'ユーザー名またはパスワードが違います。';
document.getElementById('message').style.color = 'red';
}
});
2.APIGateway用ポリシーを作成する
OCIコンソールから [アイデンティティとセキュリティ] – [ポリシー] から以下のポリシーを新規作成する。
・ ポリシー名: APIGateway
・ 説明: Webサイトホスティング用
AllOW any-user to use object-family IN TENANCY where ALL {request.principal.type= 'ApiGateway', request.resource.compartment.id = '{APIGatewayを作成予定のコンパートメントOCID}'}
3.バケットを作成する
OCIコンソールから [ストレージ] – [バケット] からバケットを新規作成する。
・ バケット名: Website-Bucket
・ デフォルト・ストレージ層: 標準
・ 暗号化: Oracle管理キーを使用した暗号化
![OCIコンソールから [ストレージ] - [バケット] からバケットを新規作成](https://www.clinks.jp/corp/wp-content/uploads/2024/12/①.avif)

作成したバケットはプライベートバケットのため 「事前認証済みリクエスト」 を作成し外部から参照できる設定にする。
・ 事前認証済みリクエスト・ターゲット: バケット
・ アクセス・タイプ: オブジェクトの読取りを許可
・ 有効期限: 100年後

作成後、事前認証済みリクエストのURLが表示されるのでコピーしておく。
※URLは一度しか表示されないため必ずコピーすること

発行されたURLが問題なく表示できるかindex.htmlにアクセスし、確認をする。
【事前認証済みリクエストURL】
https://{namespace}.objectstorage.{region}.oci.customer-oci.com/n/{namespace}/b/{bucket-name}/o/index.html
アクセス後、ログイン名、パスワードを入力しても「ログイン成功!」と表示が出ないためAPIGatewayを作成し、Webホスティング設定を行う。

4.APIGatewayを作成する
OCIコンソールから [開発者サービス] – [ゲートウェイ] からAPIGatewayを新規作成する。
・ 名前: Website-APIGateway
・ タイプ: パブリック
・ ネットワーク: パブリックサブネットが存在するネットワーク
・ サブネット: パブリックサブネット

数分後にAPIGatewayが作成されるので [デプロイメント] – [デプロイメントの作成] からAPIGatewayのルーティング設定を行う。

「最初から」 を選択し以下の情報を入力する。
・ 名前: root
・ パス接頭辞: /

APIリクエスト・ポリシーは設定せず 「次」 をクリックする。

認証は設定せず 「次」 をクリックする。

ルーティング設定を行う。
・ パス: /{req*}
・ メソッド: GET
・ バックエンド: 複数バックエンドの追加

バックエンド設定を行う。
・ セレクタ: パス
・ パス名: req

「バックエンドの定義」 をクリックし、デフォルトバックエンドを設定する。URLは手順2で作成した事前認証済みリクエストURLに「index.html」を付け加えた物を使用する。
・名前: default
・一致タイプ: いずれかの
・デフォルトに設定: 有効
・バックエンド・タイプ: HTTP
・URL: https://{namespace}.objectstorage.{region}.oci.customer-oci.com/n/{namespace}/b/{bucket-name}/o/index.html

もう一度 「バックエンドの定義」 をクリックし、jsファイルがマッピングできるようにjsファイル用バックエンドを設定する。URLは手順2で作成した事前認証済みリクエストURLに「${request.path[req]}」を付け加えた物を使用する。
jsファイル以外にtxtファイルなどある場合は拡張子別にバックエンドの定義を作成する。
・ 名前: js
・ 一致タイプ: ワイルドカード
・ 式: *.js
・ バックエンド・タイプ: HTTP
・ URL: https://{namespace}.objectstorage.{region}.oci.customer-oci.com/n/{namespace}/b/{bucket-name}/o/${request.path[req]}

2つのバックエンド定義が作成されていることを確認し、「次」 をクリックする。

設定した情報を確認し 「作成」 をクリックする。

デプロイメント作成後、ルーティング設定したURLが発行されるのでコピーする。

アクセス後、ユーザー名とパスワードを入力し、「ログイン成功!」と表示されることを確認する。

サーバレスでWebサイトを作成するためにWebサイトホスティング機能を使用して構成しました。
Webサイトがうまく表示できない場合は以下が設定できていることを確認してください。
・ APIGatewayにを作成したネットワークが外部に接続できることを確認してください。
・ APIGatewayがオブジェクト・ストレージ・バケットにアクセスするための適切なポリシーがあるか確認してください。
・ アプリケーションがバックエンド定義に拡張子をすべて追加してください。
・ この手法を使用して設定できるのは、AOT (Ahead of Time)コンパイル済アプリケーションおよび静的Webサイトのみです。アプリケーションがネイティブJavascriptコードでコンパイルされていることを確認します。
参考サイト
静的Webサイト・ホスティングのためのOCI Object StorageおよびOracle API Gatewayの設定