Googleログイン認証のトークン検証

2 min read読了の目安(約1800字

概要

Webアプリケーションを構築するときに、Google等を使った外部の認証サービスを使うと思います。最近だと、フロントエンドとバックエンドで構成を分けることが多いと思うので、ReactでGoogleログイン認証を実装してみたの記事のように、フロントエンド側でまずは認証というケースがあるかと思います。
ただ、フロントエンドで認証した場合、バックエンドでその認証が正しいものであるかを検証する必要が出てきます。Microservices における認証と認可の設計パターンの記事に書かれている、SSOパターンがイメージとして近い感じがします。
というわけで、今回はフロントエンド側で認証したGoogleログインのトークンをバックエンド側でどう検証するか、について書いてみます。

対応方法

GoogleのドキュメントのAuthenticate with a backend serverを見ると、ライブラリを使ったid_tokenの検証方法が載せられています。RESTのエンドポイントをでid_tokenをパラメータにして渡す方法も紹介されていますが、推奨ではないようです。
ドキュメントは見つけられませんでしたが、access_tokenでの認証も可能です。How can I verify a Google authentication API access token?の記事にある通り、RESTのエンドポイントが用意されているのでそこにリクエストを投げる形になります。
なお、id_tokenとaccess_tokenの違いについては、OAuth 2.0/OpenID Connectの2つのトークンの使いみちをご参照ください。

Goでの実装

上記対応の通り、ドキュメントに紹介されているライブラリを使った方法が無難なようです。ただ、ドキュメントにはGoでの実装サンプルが載っていなかったので、ここで紹介します。
対応としてはValidating Google sign in ID token in Goの記事で紹介されている通り、google-api-go-clientのライブラリを使用します。go get google.golang.org/api/oauth2/v2でインストールした後に、以下のコードでid_tokenの検証ができます。なお、試していませんがライブラリではaccess_token用のメソッドも用意されていたので、access_tokenの検証も行うこともできそうです。

func ValidateGoogleToken(idToken string) string {
	httpClient := &http.Client{}
	oauth2Service, err := oauth2.New(httpClient)
	tokenInfoCall := oauth2Service.Tokeninfo()
	tokenInfoCall.IdToken(idToken)
	tokenInfo, err := tokenInfoCall.Do()
	if err != nil {
		return ""
	}
	return tokenInfo
}