開発エンジニアのTOSHIKI.Kです。
Google Cloud 上でマルチテナントアプリを開発する際、認証部分をどのように実装するかという課題があるかと思います。
今回、マルチテナントアプリの開発にあたり、Google Cloud の認証サービスである Identity Platform で認証機能の実装をしたので、手順と方法について紹介します。
【Identity Platform について】
Identity Platform は認証とID管理を行うためのサービスです。これにより認証機能やユーザーの管理を全てサービスに一任することができます。
同じく Google Cloud の認証サービスで IAP (Identity-Aware Proxy) がありますが、IAPで利用できる認証プロバイダはGoogleアカウントのみなのに対して、Identity Platformでは、Microsoft、メール/パスワード、SAML、電話番号、匿名など様々なログイン方法が実装できます。
さらに、テナント毎にユーザーを管理できるためマルチテナントに対応しています。
【Webアプリケーションへの認証機能実装】
実際にWebアプリケーションに簡単な認証基盤を組み込んでみました。
その手順を以下にまとめます。
1.テナントの作成
Google Cloud の「管理コンソール> Identity Platform >テナント>テナントを追加」にてテナントを作成します。
※テナントIDはログイン時のテナントの識別に利用します。
2.ユーザーの作成
テナント上にユーザーを作成します。
3.ログイン方法の設定
テナント単位で許可するログイン方法を設定します。
※以下の例では、テナント「tenant-a」のユーザーがEmail/Password、Google 認証でログインできるようになります。
4.ログイン画面作成
ここまでで、Identity Platform 側での準備が整ったので、HTMLにてログイン画面を作成します。
Identity Platform で認証を行う場合、Identity Platformの認証情報を埋め込む必要があります。
以下の手順で認証情報を取得します。
作成するログイン画面のHTMLに取得した認証情報を埋め込みます。
今回作成するログイン画面は作成するためのライブラリである「FirebaseUI」を利用します。
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Login</title>
<!-- *******************************************************************************************
* 上でコピーしてきた認証情報を以下に貼り付ける
***************************************************************************************** -->
<script src="https://www.gstatic.com/firebasejs/8.0/firebase.js"></script>
<script>
var config = {
apiKey: "api_key”,
authDomain: "authDomain",
};
firebase.initializeApp(config);
</script>
<!--***************************************************************************************** -->
<script src="/__/firebase/6.2.0/firebase-auth.js"></script>
<!--firebase UIの読み込み-->
<script src="https://www.gstatic.com/firebasejs/ui/6.1.0/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.1.0/firebase-ui-auth.css" />
<script type="text/javascript">
function initializeAuthUI() {
// 使用するテナントIDを設定
// ここで入力するテナントIDによってどのテナントで認証を行うかが決まる
var tenantId = document.getElementById('tenantIdInput').value;
if (tenantId) {
firebase.auth().tenantId = tenantId;
var ui = new firebaseui.auth.AuthUI(firebase.auth());
ui.reset();
ui.start('#firebaseui-auth-container', uiConfig);
} else {
alert('テナントIDを入力してください。');
}
}
var uiConfig = {
callbacks: {
signInSuccessWithAuthResult: function (authResult, redirectUrl) {
//trueにするとsignInSuccessUrlで定めた場所にリダイレクトされる
//falseにするとページは遷移しない
return true;
},
uiShown: function () {
// ログイン画面が出たときに行う作業
}
},
signInFlow: 'popup',
//認証成功後のページ
signInSuccessUrl: './success.html',
signInOptions: [
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.GoogleAuthProvider.PROVIDER_ID
],
// 利用規約のページ
tosUrl: './terms-of-services.html',
// プライバシーポリシーのページ
privacyPolicyUrl: './privacy-pocily.html'
};
</script>
</head>
<body>
<div>
<label for="tenantIdInput">テナントID:</label>
<input type="text" id="tenantIdInput" placeholder="テナントIDを入力">
<button onclick="initializeAuthUI()">認証を開始</button>
</div>
<div id="firebaseui-auth-container"></div>
</body>
</html>
以下が実際の画面です。サインイン、サインアップが可能です。
※上記画面は Firebase UI によるデフォルトのログイン画面ですが、以下のように、任意のログイン画面にカスタマイズすることも可能です。
5.サーバサイドの処理
ログイン成功後、accessToken が発行されます。accessTokenをサーバーサイドに送り、検証を行うことで、認証されたユーザーであれば後続の処理を許可するといったことが可能です。
verify.py(accessTokenをsessionで渡した場合)
from firebase_admin import *
if request.session.get('accessToken'):
try:
id_token = request.session.get('accessToken')
decoded_token = auth.verify_id_token(id_token,app=self.default_app)
#検証に成功した場合、ユーザー情報を取得
uid = decoded_token['uid']
#後続の何らかの処理
# tokenの有効でない場合
except (InvalidIdTokenError) as e:
print(f"InvalidIdTokenError: {e}")
# tokenの有効期限が切れていたい場合
except (ExpiredIdTokenError) as e:
print(f"ExpiredIdTokenError: {e}")
【まとめ】
Identity Platform を利用することで、複数のログイン方法が可能な認証基盤をマルチテナントのアプリケーションに簡単に組み込むことができました。
上記の記事内にて気になったことがございましたら、ぜひお気軽にお問い合わせください。
【参考情報】
Identity Platform を使用してユーザーがメールアドレスでログインできるようにする
マルチテナンシーを使用した認証
上記の記事に関するご質問や、Google Cloud ・ Google Workspace に関するお困りごとがございましたらお問い合わせください。