🌐
第四回:GCPでログイン機能を作ってみた
2025-01-08
約6275字
さかもも
目次
はじめに
ログイン認証をどうやって実現したか
Identity Platformとは?
Identity Aware Proxyとは?
認証関連について構築した構成図
インフラの構成手順
1. Cloud Runの構築(バックエンド側)
2. Identity Platformの設定(初期化)
3. Identity Aware Proxyの設定(初期化)
4. ドメインの取得
5. SSL証明書の取得
6. Load Balancingの構築
7. DNSの設定
8. IAPの設定
9. Cloud Runの構築(フロントエンド側)
各フローの実装周りの話
ログイン認証 + IDトークンの保持
バックエンドへのリクエスト
まとめ
現在、趣味でWebサービスを作っていますが、そのWebサービスに対して、ログイン認証機能を構築することで、特定のユーザーだけがアクセスできるようにしたいと思いました。
※現在使っているサービスの機能は過去の下記記事に記載しております。
ログイン認証はいくつもの実現方法があると思いますが、今回はサービスをGCP環境に構築しているのもあるため、GCP上のサービスを使って、ログイン認証を実現することを考えました。
そこで、Identity PlatformとIdentity Aware Proxyを利用して、ログイン認証を実現することを考えました。
構成イメージとしては、下記が限りなく近いです。要因としては、下記が挙げられます。
端的に言うと、GCPで提供している認証サービスです。Firebase Authenticationの上位互換なイメージです。詳細は下記の記事にまとまっておりますので、ご覧いただけると幸いです。
OIDC、SAMLなどの認証方式をサポートしていますが、今回はシンプルにEメールアドレス・パスワード認証としています。
※この場合、GCPコンソールで、Identity Platformの画面からユーザーを追加することも可能です。
端的に言うと、APIサーバーなどのリソースを保護するためのサービスになります。シンプルに認証されたユーザーのみをアクセス可能にするだけではなく、ユーザーごとにアクセス制御を行うことも可能です。詳細は下記の記事やドキュメントをご覧ください。
今回は、バックエンドのAPIサーバーとしてCloud Runを利用しているため、IAPを用いて、Runへのアクセス制御を行います。
下記のような構成図となります。処理フローとしては、下記です。
上記それぞれのステップにおいての実装周りの話は後述します。その前に、上記インフラを構築する際の手順について触れていきます。
前述した認証に関する構成を組むために、下記に箇条書きとなりますが、手順を記載します。
※多くの手順はterraformで組もうと思って実装中ですが、一部はterraformで自動的な構築ができない部分もあります。OAuth認証画面の構築などが該当します。
大まかに下記のステップとなります。それぞれのステップについて、詳細を見ていきます。
以下の手順が必要となります。ただし、下記は、今回のログイン認証周りとはあまり関連しないため、私の作ったサービスでは必要という理解で大丈夫です。
以下の手順が必要となります。まずは、Identity Platformを利用可能な状態にします。
下記は全て、google cloud console上で実施が可能です。
以下の手順で、Identity Aware Proxyが利用可能となります。
下記も全て、google cloud console上で実施が可能です。
※★マークがついた部分は、terraformでの自動構築ができない部分となります。
HTTPS通信とするため、SSL証明書が必要となりますが、その際にドメインも必要となります。そこで、ドメインの取得も行います。
今回は、GCPのCloud Domainsを使って、ドメインを取得します。下記の手順となります。同様にgoogle cloud console上で実施が可能となります。
SSL証明書を構築します。
具体的な手順は、こちらのドキュメントから確認が出来ます。
ドメインは前述で作成したものを利用すれば良いです。このタイミングでは、SSL証明書のステータスは、provisioningのままとなります。
Load Balancingを作成します。先ほどのSSL証明書の構築手順と関連して、こちらのドキュメントが参考になります。手順の概要は下記となります。
取得したドメインとLBの紐付けを行います。
今回はDNSプロバイダとして、Cloud DNSを利用します。Cloud DNSの画面から、LBのIPをwwwなどのAレコードに対して、設定します。詳細な手順はこちらをご覧ください。
Identity Aware Proxyの設定を行い、バックエンド側のRunへのアクセス時にガードをかけるようにします。下記手順となりますが、全てgoogle cloud console上(IAPの設定画面)で実施が可能です。
最後にフロントエンド側のRunの設定を行い、デプロイします。
基本的な手順はこちらを参照してください。
注意点としては、secret/config.jsonのapiKeyやauthDomainは、Identity Platformの「アプリケーションの構成」画面から確認が可能です。
最後に各フロー(前述した3ステップ)の実装周りの話について触れていきます。
こちらの実装が参考になります。
class LoginHelper:
def __init__(self) -> None:
# Identity Platformの認証処理を行うためのインスタンスを取得
with open(os.path.join(os.path.dirname(__file__), "secret", "config.json")) as f:
firebase_config = json.load(f)
app = pyrebase.pyrebase.initialize_app(config=firebase_config)
self.__auth = app.auth()
def login(self, email: , password: ) -> User:
try:
user = self.__auth.sign_in_with_email_and_password(email, password)
return User(email=email, id_token=user["idToken"])
except Exception as e:
raise IdentityPlatformException(f"Sign in Error is occured! Exception detail is ")
secret/config.jsonに格納した情報から、接続先のプロバイダー情報を判別して、接続をしてくれます。Firebase APIのラッパーライブラリであるpyrebaseを利用しています。
sign in処理で帰ってきたレスポンスからIDトークンを取得しています。(このIDトークンをバックエンドのリクエスト時に利用します)
こちらの実装が参考になります。
def request_api(self, token: , request_name: , data: ) -> Response:
url = f"/"
resp = requests.request(
"POST",
url,
data=json.dumps(data),
headers={"Content-Type": "application/json", "Authorization": "Bearer {}".format(token)},
)
if resp.status_code != 200:
raise Exception(
"Bad response from application: {!r} / {!r} / {!r}".format(resp.status_code, resp.headers, resp.text)
)
else:
return resp
シンプルにrestfulなAPIに対するリクエストではあるんですが、Authorization: Bearerヘッダに対して、先ほど認証処理時に取得したIDトークンを付与していることに注意です。
※このトークンがないと、バックエンドのRunの前段にあるIdentity Aware Proxyに弾かれて、リクエストがRunまで届きません。
GCPのIdentity PlatformとIdentity Aware Proxyを利用して、特定のユーザーのみがサービスを使えるような環境を構築してみました。
GCP上で公開するサービスを作る際の参考になれば幸いです。ただし、考慮が不足している点(例えば、IDトークンの有効期限が切れたら、リフレッシュさせるなど)もあったりするので、サービス構築に必要な要件を整理して、適切にセキュアなサービスを構築するのが望ましいと思います。
©︎ 2025 - Yard