面倒なアプリのログイン機能を超簡単に実装する on GCP
この記事は Google Cloud Japan Customer Engineer Advent Calendar 2019 の 16日目の記事です。
tl;dr
「Google アカウントを使ったログイン機能を簡単に実装したい!」 Identity-Aware Proxy を使えば、ログイン画面すら作ることなく Google アカウントによるログイン機能を実装できます。ログイン可能なユーザを制限した社内向けアプリ等にも最適です。
「Google アカウント以外のソーシャル ログインもサポートしたい!」
Identity Platform で簡単に実現することができます。Firebase Authentication と共通の SDK が提供されており、ログイン画面も FirebaseUI により簡単に作ることができます。メールアドレスによるユーザリンク機能、マルチテナント対応、SLA も備わっており、コンシューマ向けアプリに最適です。
1. はじめに
多くの Web アプリケーションで以下のような画面を見たことがありますよね?
Web アプリケーションにおける最も基本的な機能の一つであるログインです。皆さんはどのように実装していますか?
本記事ではこのログイン機能を GCP のサービスを利用して簡単に実装していく方法をご紹介します。
デモアプリ
試しに以下のようなアプリを作ってみました。
……アプリケーションと呼ぶのが心苦しいほどシンプルですね!
これは Google AppEngine (GAE) を利用して作りましたが、以降ご紹介するものは Google Kubernetes Engine (GKE) や Google Compute Engine (GCE) 、はたまたオンプレミスのアプリケーションでも同様にお使いいただくことができます。
コードは以下の通りです。Node.js を使っています。
- app.js
const express = require('express')
const handlebars = require('express-handlebars')const app = express()
app.engine('hbs', handlebars({ extname: 'hbs' }))
app.set('view engine', 'hbs')
app.set('views', `${__dirname}/views`)app.get('/home', (req, res) => {
res.render('home', { layout: false })
})app.get('/error', (req, res) => {
res.render('error', { layout: false })
})app.listen(8080, () => console.log('Running on 8080'))
- views/home.hbs
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<title>Auth Sample</title>
</head><body>
<h1>ホーム</h1>
<p>
こんにちは!
</p>
</body></html>
2. Identity-Aware Proxy を使う
まずは最もシンプルに Google アカウントによるログインを実装してみましょう。
とにもかくにも、Identity-Aware Proxy をメニューから探してみます。セキュリティ -> Identity-Aware Proxy と辿るとあるはずです!
OAuth 同意画面を構成せよ、と出ていますね。[同意画面を構成] に行ってみましょう。
上のような画面が出てきたと思います。ここでは、
- アプリケーション名
を設定しました。また、今回私はカスタム ドメインを利用しているので、承認済みドメインに今回のデモ用のドメインも追加しています。
さて、再び Identity-Aware Proxy の画面に戻りましょう!
App Engine アプリの行に、IAP という列があり、OFF 状態のトグルスイッチがありますね。
これを有効にしてからもう一度アプリにアクセスしてみます。
Google アカウントのログイン画面にリダイレクトされました!
IAP を利用することで、ほぼスイッチを ON にするだけでこのようなログイン機能を実装することができます。
さて、それでは適当なアカウントでログインしてみようと思いますが……
おっと、アクセス権がないと怒られてしまいましたね。
先程の Identity-Aware Proxy の画面に戻り、アプリへのアクセス権を持つアカウントを設定しましょう。
先程スイッチを ON にした GAE の列を選択してみます。すると、右側に次のような画面が出てくるはずです。
アプリにアクセスできるメンバーとして以下のようなものを追加できます。
- Google アカウント (G Suite, Cloud Identity, Gmail アカウント)
- Google グループ
- 組織ドメイン
- サービス アカウント
私の Google アカウントを “IAP-secured Web App User” という役割と共にメンバーに追加しました。
それではもう一度アプリにアクセスしてみます。
無事アプリにアクセスできていますね。Identity-Aware Proxy を利用することで、コードに一行も手を加えることなくログイン機能を実装できました。
また、多くのケースではアプリ側でログインしてきたユーザの情報を使い、提供するコンテンツを変えたりといったことをすると思います。
アプリケーションに渡ってくるリクエスト ヘッダを見てみましょう。
...
"x-goog-authenticated-user-id": "accounts.google.com:104512994084964982797",
"x-goog-authenticated-user-email": "accounts.google.com:tech@topy.work",
"x-goog-iap-jwt-assertion": "eyJhbGciR5...中略...wmqZQA3HNg"
...
“x-goog-iap-jwt-assertion” というヘッダに JWT 形式の ID トークンが入ってきています。このトークンを検証することで、正しく Identity-Aware Proxy から発行されたものであることを確認できます。
また、このトークンの中にはユーザ ID とメールアドレスが入っています。万が一設定のミス等により Identity-Aware Proxy をバイパスされてしまった場合、”x-goog-authenticated-user-id/email” は偽造されるおそれがありますから、トークン内の情報を使うのが良いでしょう。
この情報と、例えば Cloud Firestore を使ってユーザ情報を管理することで、ログインしているユーザに合わせたコンテンツを提供することができます。
より詳しい実装方法は、皆さんのアプリケーションの動いているプラットフォームに合わせて、以下のドキュメントを参照してください。
- GAE: https://cloud.google.com/iap/docs/app-engine-quickstart?hl=ja
- GKE: https://cloud.google.com/iap/docs/enabling-kubernetes-howto?hl=ja
- GCE: https://cloud.google.com/iap/docs/enabling-compute-howto?hl=ja
- オンプレ (IAP コネクタ使用): https://cloud.google.com/iap/docs/enabling-on-prem-howto?hl=ja
まとめ
ここまで、Identity-Aware Proxy について見てきました。 Identity-Aware Proxy は次のようなケースに最適です。
- ID プロバイダとして Google を利用している
- ユーザの限定された社外向け、社内向けアプリケーション
3. Identity Platform を使う
先程の Identity-Aware Proxy では、Google アカウントを使ったログイン機能を簡単に実装できました。
それでは、例えばコンシューマ向けアプリケーションのように、Google アカウント以外の ID プロバイダのログインも提供したい場合はどうすれば良いでしょうか。
GCP では、そういった用途のために Identity Platform (ID プラットフォーム) を提供しています。
GCP のコンソールから、ツールカテゴリにある Identity Platform のページに行ってみましょう。
[プロバイダを追加] によって、有効にする ID プロバイダを選択することができます。ID プロバイダとして
- OpenID Connect
- SAML
- SNS 等の外部サービス (Google など)
- 電話番号
- メール / パスワード
といったものをサポートしています。
Identity-Aware Proxy で行った Google アカウントでのログインを Identity Platform でもやってみましょう。
まず、ID プロバイダとして “Google” を選択します。
Web Client ID と Web Client Secret というものが必要なようです。
意図しないアプリからユーザの Identity を利用されてしまっては困るので、利用するWeb アプリ (= クライアント) をここで指定するわけですね。(詳しく知りたい方はこちらへ!)
画面の指示に従って、”API とサービス” をクリックします。
[認証情報を作成] というボタンがありますから、こちらから “OAuth クライアント ID” を選択して作成します。
ここでは “ウェブ アプリケーション” を選び、名前を入力します。[作成] を押すと Web Client ID と Web Client Secret が表示されますから、これを ID プロバイダ Google の設定画面にコピーしましょう。
これでコンソールでの操作は完了です!
続いて、少しデモアプリの方に手を加えましょう。
Identity Platform は Firebase Authentication というサービスと同じインフラストラクチャの上に作られており、現在は同じ SDK を使っています。また、FirebaseUI というログイン機能のフロント インターフェースを簡単に作ることのできるツールも使えます。
その場合、ID プロバイダを選択するボタンを配置する必要があるので、そのための画面を login.hbs として用意しました。
FirebaseUI を使って Google アカウントによるログインを実装すると以下のようなものになります。
- login.hbs
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<title>Auth Sample</title>
<script src="https://www.gstatic.com/firebasejs/7.6.0/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/ui/4.3.0/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.3.0/firebase-ui-auth.css" />
<script>
var config = {
apiKey: "xxxxxxxxxxxyyyyyyyyyzzzzzzzzzzz",
authDomain: "xxxxx.firebaseapp.com"
}
firebase.initializeApp(config) var uiConfig = {
signInSuccessUrl: '/home',
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID
]
} var ui = new firebaseui.auth.AuthUI(firebase.auth())
ui.start('#firebaseui-auth-container', uiConfig)
</script></head><body>
<h1>ログイン</h1>
<div id="firebaseui-auth-container"></div>
</body></html>
Firebase SDK, FirebaseUI を追加し、apiKey 等の設定を作成し、AuthUI に渡して ui を生成しています。
apiKey と authDomain は Identity Platform の右上の [アプリケーション設定の詳細] を確認すると、Web, Android, iOS 用のスニペットが表示されるので、それをそのままコピーします。
このページをデプロイし、アクセスしてみると
というよく見かけるボタンが <div> 要素に挿入されました。これをクリックすると、Identity-Aware Proxy の方で見たような Google アカウントのログイン画面に遷移します。
Identity Platform を利用した場合、認証のフローや ID トークンを取得することは非常に簡単ですが、バックエンド アプリケーションの方にトークンの検証等を行う処理を入れる必要があります。詳しくは以下のドキュメントや、Firebase Authentication のドキュメントを参考にしてください。
トークンの処理も Firebase Admin SDK を使うことで簡単に実現できるようになっていますよ。
さて、Identity Platform はこういった SDK の提供だけでなく、ログインしたユーザの管理もできます。。Identity Platform のユーザタブを見てみましょう。
私のログインした Google アカウントがユーザとして追加されていますね。Identity Platform では
- Identity Platform 上でユニークなユーザ ID (UID) の生成
- 複数プロバイダをメールアドレスでリンク
- 元の ID プロバイダのトークンの取得
- マルチテナントでの複数アプリの管理
といった機能が提供されており、Firebase Authentication とは異なり SLA もあるエンタープライズ向けのサービスとなっています。
まとめ
Identity-Aware Proxy に続いて Identity Platform を見てきました。Identity Platform は次のようなケースに最適です。
- コンシューマ向けのサービス (モバイル アプリケーション含む)
- Google だけでなく様々な外部サービス、SAML を利用したログインを提供したい
おわりに
GCP でログイン機能を提供するサービスについて紹介しました。特に Identity-Aware Proxy はユニークなサービスかと思いますが、とても便利なのでアプリケーションを作る際にはぜひ使ってみてください。
明日はネットワーク スペシャリストである Seiji Ariga さんによる「GCP の細かすぎて伝わらないハイブリッドネットワーキング」です。
お楽しみに!