inthisfucking.world

💩🌎

static siteにユーザ認証を設ける

static site generatorを利用して、自分のプロジェクトやプロフィールのサイトを構築することは良くあると思います。static site generatorの出力は、読んで字の如く、静的なファイルです。多くの場合は、それらをgithubなどのサードパーティーのサービスを使用して配信するでしょう。とても楽で便利ですね。

実際に運用を続けていると、stagingの環境が欲しくなることがあります。単純に、productionとは別にstagingの段階のファイルをgithubなどで配信するので問題ありませんが、stagingの環境は公にアクセスを許可したくないこともあるでしょう。

この記事では、static site generatorを利用したサイトにおいて、Google Accountによる認証を設ける方法について書きます。

背景

レンタルサーバーなどで自分である程度http serverの設定ファイルなどを管理出来る場合は、http serverの機能として提供されているbasic認証を有効にすることも出来るでしょう。しかし、githubなどのサードパーティーのサービスを利用している場合は、そこまで自分で管理出来ないことも多々あります。実際に、現時点では、GitHub Pagesにおいてbasic認証などの認証を設ける機能は提供されていません。

勿論、static site generatorで出力されたhtmlの方で、つまりクライアント側で認証することは可能ですが、ここではあくまでstatic siteを配信する際にサーバ側で認証を行いたいものとします。

Google Cloud PlatformのIdentity-Aware Proxy

Google Cloud Platform (以下GCP) には、Identity-Aware Proxy (以下IAP) というものがあります。これは、httpsのリクエストがGCPのネットワークに入る際にユーザの認証を設けることが出来るサービスです。ここで言うユーザの認証とは、Google Accountによる認証です。

IAPは、App Engine (以下GAE) をサポートしています。static site generatorで出力した静的ファイルをGAEで配信し、IAPでGoogle Accountによる認証を設けることで、特定のGoogle Accountでサインインした場合だけアクセスできるstatic siteを構築することが出来ます。

GAEで静的ファイルを配信する

GAEは色々なプログラミング言語が使用できますが、ここではgoを使用することを前提とします。ここでは、以下の構成によってGAEを利用して静的ファイルを配信します:

GAEのappをgoを使用して書く方法に関しては、Quick Startを参照下さい。参考までに、main.goのコードはこんな感じになります。

package main

import (
	"log"
	"net/http"
	"os"
)

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("Defaulting to port %s", port)
	}

	panic(http.ListenAndServe(":"+port, http.FileServer(http.Dir("./public"))))
}

単純に、publicディレクトリ以下のファイルを、http.FileServerを利用して配信しています。

app.yamlは以下の通りです。こちらも、必要最低限の設定しかしていないので、app.yamlで指定できるオプションを参照し、ご自身の必要に合わせて設定して下さい (特に、どういう風にスケールさせるかの部分は料金にも関わってきます)。

runtime: go111

handlers:
  - url: /.*
    secure: always
    redirect_http_response_code: 301
    script: auto

これらのファイル/ディレクトリが準備できたら、gcloud app deploy <path_to_app_yaml>でGAEにdeploy出来ます。

IAPを有効化し、設定する

こちらの記事に、IAPをGAEのappに対して有効にして、アクセスを許可するGoogle Accountを設定する一連の手順が掲載されていますので、詳しくはそちらをご参照下さい。その記事では、GAEのappを書くのにpythonを使用していますが、IAPをGAEのappに対して有効にしたりする部分はgoの場合と変わりません。

Google Cloud Consoleにて、GAEのappをdeployしたプロジェクトを指定し、IAPの項目を見ると、先程deployしたGAEのappが表示されているはずです。

GAE app listed on IAP page

IAPを有効にしたいGAEのappの行に表示されているトグルボタンを押して、対象のGAEのappに対してIAPを有効にします。

後は、最後に当該のGAEのappに対してアクセスを許可するGoogle Accountを設定します。設定したいGAEのappが表示されている行のチェックボックスにチェックし、ページの右上の辺りにあるSHOW INFO PANELボタンを押します。そこで表示されたADD MEMBERボタンを押し、アクセスを許可するGoogle Accountを追加します (i.e. なんとか@gmail.com)。

Google Accountを追加する際は、__IAP-secured Web App UserというIAMの権限のみを与える形で追加__しましょう。それ以外の権限を与える形でGoogle Accountを追加してしまうと、追加したユーザは与えられた権限を行使出来るようになります。例えば、Project Editor権限を与える形で追加してしまうと、そのGoogle Accountはそのプロジェクトに関わる色々な事を実行出来てしまうので、セキュリティーの問題になり得ます。

Adding a Google Account that can access the GAE app

これで、追加したGoogle Accountのみアクセス出来るstatic siteが構築出来ました。追加したGoogle Accountでサインインした場合はアクセスが出来、それ以外だとアクセスが出来ないのを確かめてみて下さい。

料金

static siteをGitHub Pagesで運用する場合、料金が発生しないことは大きな利点の一つだと思います。IAPをGAEに対してのみ使っている場合は、IAPに対する料金は発生しません。しかし、GAEは料金が発生します。そんなにアクセスがない場合は、無料枠で事足りると思いますが、アクセスの量によっては料金が発生することを覚えておくと良いでしょう。