Google Sign-Inは、モバイルおよびウェブアプリケーションでGoogleアカウントによるユーザー認証を実装するGoogleのSDKです。この技術はOAuth 2.0プロトコルに基づいており、サードパーティアプリケーションにパスワードを渡さずにGoogle APIへのアクセストークンを取得できます。30億以上のAndroidデバイスがGoogle Sign-Inをサポートしており、モバイルアプリで最も一般的なログイン方法となっています。Google Identity Platform、2025年によると、SDK統合により登録時間が60%短縮され、ユーザーコンバージョンが向上します。
主なポイント
Google Sign-Inは、サードパーティアプリケーションでのユーザー認証のためにGoogleが提供するシングルサインオン(SSO)サービスです。SDKにより、開発者は独自の登録システムを作成せずにGoogleアカウントによるログインを統合できます。この技術はOAuth 2.0プロトコルとOpenID Connectに基づいており、ユーザーの名前、メール、アバター、一意のIDなどの識別情報を提供します。
従来のメールとパスワードによる認証とは異なり、Google Sign-Inはパスワードを覚えたり登録手続きを行う必要がありません。ユーザーはデバイスでGoogleアカウントを選択し、権限を確認すると、アプリがアクセストークンを受け取ります。Google Identity Platform(2025年)によると、Google Sign-Inを導入したアプリは、メール/パスワード形式と比較して52%多くの登録成功数を示しています。
Google Sign-Inは3つの使用シナリオをサポートしています:ユーザー認証(ID Tokenの取得)、Google APIへのアクセス承認(Access Tokenの取得)、および既に認可されたユーザーのためのシームレスな認証(Silent Sign-In)です。各シナリオには異なるスコープセットが必要で、異なるタイプのトークンが返されます。
OAuth 2.0は、アプリがユーザーの資格情報を開示せずにユーザーリソースへの制限付きアクセスを取得できるようにする認可プロトコルです。Google Sign-Inのコンテキストでは、プロトコルは次のように機能します:アプリはGoogleを通じてユーザーに認可を要求し、一時的な認可コードを受け取り、それをアクセストークンと交換し、そのトークンを使用してGoogle APIを呼び出します。
OAuth 2.0の以前のプロトコルとの主な違いは、リソース所有者(ユーザー)、クライアント(アプリ)、認可サーバー(Google)、リソースサーバー(Google API)間の役割の分離です。アプリはユーザーのパスワードを決して受け取らず — 取り消し可能なトークンのみを受け取ります。Google Identity PlatformはOAuth 2.0の上でOpenID Connect仕様を使用し、JWT形式の標準化されたID Tokenを追加します。
// Credential Manager経由でID Tokenを取得する例
val googleIdOption = GoogleIdCredentialOption.Builder()
.setServerClientId(serverClientId)
.build()
val credentialManager = CredentialManager.create(this)
val request = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
credentialManager.getCredential(request)
.addOnSuccessListener { result ->
val credential = result.credential as GoogleIdCredential
Log.d("SignIn", credential.idToken)
}ID Token(JWT)には3つのセグメントがあります:署名アルゴリズムを含むヘッダー、ユーザーデータ(sub、email、name、picture)を含むペイロード、および検証用の署名です。アプリのサーバー側はGoogleの公開鍵を使用してID Tokenの署名を検証し、ユーザー識別子を抽出します。このアプローチにより、クライアントアプリが侵害された場合でも、攻撃者はGoogleの秘密鍵にアクセスできなければトークンを偽造できないことが保証されます。
Credential Managerは2023年に導入された最新のAndroid APIで、すべての認証方法(Google Sign-In、パスワードログイン、Passkeys)を単一のユーザーインターフェースに統合します。古いGoogleSignInClientとは異なり、Credential ManagerはログインにWebViewを必要とせず — ネイティブのBottom Sheetを使用するため、認証が高速化され、ユーザーエクスペリエンスが向上します。
Credential Managerの主な利点は、すべての資格情報タイプに対する統一されたUXです。ユーザーは1つのダイアログで、Googleでログイン、Passkeyの使用、パスワードの入力から選択できます。開発者は異なる認証フローを管理する必要がなく — Credential ManagerがGoogle Sign-In、Smart Lock、Passkeysとのやり取りを抽象化します。GoogleはAndroid 14+向けのGoogle Sign-In統合の主要な方法としてCredential Managerを推奨しています。
| パラメータ | GoogleSignInClient(レガシー) | Credential Manager |
|---|---|---|
| 最小API | Android 4.4(API 19) | Android 4.4(API 19) |
| インターフェース | WebView / BottomSheet | ネイティブBottomSheet |
| Passkeyサポート | いいえ | はい |
| SDKサイズ | 約500 KB | 約150 KB |
| ステータス | 非推奨(2024年) | Google推奨 |
移行 GoogleSignInClientからCredential Managerへの移行には、クライアント側のロジックの変更が必要です:GoogleSignInOptionsの代わりにGoogleIdCredentialOptionを使用し、GoogleSignIn.getSignedInAccountFromIntentの代わりにGetCredentialResponseを通じて結果を処理します。ID Tokenは同じJWT形式を維持するため、サーバー側の変更は必要ありません。Google I/O 2024によると、Google Play上のアプリの約40%がすでにCredential Managerに移行しています。
Google Sign-InをAndroidアプリに統合するには、Google Cloud Consoleでプロジェクトを設定することから始めます。最初のステップは、Android用のOAuth 2.0 Client IDを作成することです:アプリのパッケージ名とSHA-1証明書フィンガープリントを指定します。Googleはこのデータを使用して、認証リクエストが偽のクライアントではなくあなたのアプリから来ていることを検証します。
Google Cloud Consoleでクライアントを作成した後、開発者はbuild.gradleにCredential Managerの依存関係を追加し、serverClientIdでGoogleIdCredentialOptionを構成します。重要:serverClientIdは同じGoogle CloudプロジェクトのウェブアプリケーションのClient IDであり、サーバー側がID Tokenを検証するために使用します。クライアントアプリはトークンを検証せず — 受信してサーバーに転送するだけです。
// build.gradle (app) dependencies
implementation("androidx.credentials:credentials:1.5.0")
implementation("androidx.credentials:credentials-play-services-auth:1.5.0")
implementation("com.google.android.libraries.identity.googleid:googleid:1.1.0")
// Credential Manager経由でGoogle Sign-Inをリクエスト
suspend fun requestGoogleSignIn(context: Context): String? {
val credentialManager = CredentialManager.create(context)
val googleIdOption = GoogleIdCredentialOption.Builder()
.setServerClientId(BuildConfig.SERVER_CLIENT_ID)
.setAutoSelectEnabled(true)
.build()
val result = credentialManager.getCredential(
context as Activity,
GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
)
return (result.credential as GoogleIdCredential).idToken
}クライアントでID Tokenを受信した後、アプリはそれをサーバーに送信し、そこで検証が実行されます。サーバーはGoogleの公開鍵(https://www.googleapis.com/oauth2/v3/certsで利用可能)、トークンの有効期限(exp)、およびaudフィールドの値を使用してJWT署名を検証します — serverClientIdと一致する必要があります。検証後、サーバーは独自のセッションを作成し、例えば内部JWTまたはSession Tokenを発行します。
iOSでのGoogle Sign-Inの統合は、CocoaPodsまたはSwift Package Managerを介して利用可能なGoogleSignIn-iOS SDKを通じて行われます。設定プロセスには、Google Cloud ConsoleでiOS用のClient IDを作成し(Bundle Identifierを指定)、コールバック用のURL Schemeを追加し、認証後にGoogleから返されるURLを処理するためのAppDelegateの設定が含まれます。
Google Sign-InのiOSバージョンのAndroidとの重要な違いは、URL SchemeとInfo.plistを設定する必要があることです。GoogleSDKはコールバックにUniversal Linksを使用しますが、フォールバックとして`com.googleusercontent.apps.[CLIENT_ID]`形式のURL Schemeが必要です。アプリの起動間でリフレッシュトークンを保存するために、Keychain Sharingの設定も必要です。Google Identityのドキュメントによると、iOS SDKはiOS 15以上をサポートしています。
// iOSでのGoogle Sign-In設定
import GoogleSignIn
class SignInManager: ObservableObject {
func signIn(presenting viewController: UIViewController) {
GIDSignIn.sharedInstance.signIn(
withPresenting: viewController
) { signInResult, error in
guard let result = signInResult else {
print("Sign in failed: \(error)")
return
}
let idToken = result.user.idToken.tokenString
// ID Tokenをサーバーに送信
sendTokenToBackend(idToken)
}
}
}iOSでは、Google Sign-Inは以前に認可したユーザーに対してSilent Sign-Inをサポートしています。restorePreviousSignInメソッドは、リフレッシュトークンがKeychainに保存されている場合、自動的にセッションを復元します。これは、ユーザーが起動のたびに再ログインする必要がないアプリにとって特に重要です。Googleによると、アクティブなGoogleセッションがあるデバイスでは、Silent Sign-Inが85%のケースで成功します。
Google Sign-Inのセキュリティは3つのレベルで構築されています:クライアント検証(SHA-1アプリ署名)、トランスポート暗号化(HTTPS/TLS)、および暗号化JWT署名です。Googleから受け取ったID Tokenは、RS256アルゴリズム(SHA-256を使用したRSA)で署名されています。アプリのサーバー側は、トークンの署名、有効期限、および発行者(iss)— accounts.google.comのみ — を検証する必要があります。
Access Tokenは一時的なトークン(有効期間1時間)で、Google API(Google Drive、Google Calendar、YouTubeなど)へのアクセスを提供します。ID Tokenとは異なり、Access Tokenにはユーザー情報は含まれず — Google APIサーバーがリクエストの認可に使用する不透明な文字列です。Refresh Tokenは長期有効なトークンで、ユーザーが再ログインすることなく新しいAccess Tokenを取得できます。Refresh Tokenは最初のログイン時のみ発行され、ユーザーはGoogleアカウント設定で取り消すことができます。
// サーバーでのID Token処理例(疑似コード)
fun verifyGoogleToken(idToken: String): User? {
val verifier = GoogleIdTokenVerifier.Builder(
NetHttpTransport(), GsonFactory.getDefaultInstance()
).setAudience(listOf(CLIENT_ID))
.build()
val token = verifier.verify(idToken) ?: return null
val payload = token.payload
return User(
id = payload.subject,
email = payload.email,
name = payload.get("name") as String
)
}セキュリティ推奨事項:ID Tokenを安全でないチャネルで送信しないでください。すべてのサーバーリクエストにHTTPSを使用し、トークンの有効期限(expフィールド)と発行者(iss)を確認してください。クライアント側では、暗号化なしでSharedPreferencesにトークンを保存しないでください — EncryptedSharedPreferencesまたはAndroid Keystoreを使用してください。Google Sign-Inはサーバー間認証を目的としておらず — その場合はService Accountsを使用してください。
Credential ManagerとViewModelを使用したAndroidアプリへのGoogle Sign-In統合の完全な例。アプリはサインインボタンを表示し、認証後にID Tokenをサーバーに送信し、ユーザー情報を表示します。コードはCredential Managerとの非同期処理にコルーチンを使用しています。
class SignInViewModel: ViewModel() {
private val cm = CredentialManager.create(getApplication())
private val googleOption = GoogleIdCredentialOption.Builder()
.setServerClientId(BuildConfig.SERVER_CLIENT_ID)
.build()
suspend fun signIn(): SignInResult {
return try {
val response = cm.getCredential(
GetCredentialRequest.Builder()
.addCredentialOption(googleOption)
.build()
)
val credential = response.credential as GoogleIdCredential
SignInResult.Success(credential.idToken)
} catch (e: GetCredentialCancellationException) {
SignInResult.Cancelled
}
}
}
sealed class SignInResult {
data class Success(val idToken: String) : SignInResult()
data class Error(val message: String) : SignInResult()
data class Cancelled : SignInResult()
}認証が成功した後、アプリは検証とセッション作成のためにID Tokenをサーバーに送信する必要があります。HTTPSを使用し、POSTリクエストの本文にトークンを含めることを推奨します。サーバーは独自のセッショントークンを返し、クライアントはそれをEncryptedSharedPreferencesに保存します。サーバーへの後続のリクエストごとに、Google ID Tokenではなく内部トークンが使用されます。
最初のよくあるエラーはSHA-1証明書の不一致です。Google Cloud ConsoleはOAuth 2.0 Client IDをSHA-1証明書フィンガープリントにバインドします。アプリがデバッグキーでビルドされているが、Client IDがリリースキー用に作成された場合、Google Sign-Inはエラー12501(SIGN_IN_FAILED)を返します。解決策:Google Cloud Consoleに両方のSHA-1フィンガープリント(デバッグとリリース)を追加するか、開発用と本番用に別々のClient IDを使用します。
2番目に頻繁な問題は、serverClientIdの誤りです。開発者はしばしば、Credential ManagerのserverClientIdパラメーターにウェブアプリケーションのClient IDの代わりにAndroidのClient IDを使用します。Googleはサーバー検証用のID Tokenを生成するために、ウェブクライアントIDを正確に要求します。Android Client IDは認証中にアプリを識別するためだけに使用されます。serverClientIdがGoogle Cloud Consoleのウェブアプリケーションと一致することを確認してください。
3つ目のエラーはキャンセル処理の無視です。ユーザーは認証を完了せずにGoogle Sign-Inダイアログを閉じる可能性があります。Credential ManagerはGetCredentialCancellationExceptionをスローし、これは他のエラーとは別に処理する必要があります。多くの開発者はすべての例外をエラーとして処理し、ユーザーが単に操作をキャンセルしただけなのに “ログインに失敗しました” というメッセージを表示します。正しい処理:キャンセル時 — 何も表示せず、初期状態に戻ります。
よくある質問
AndroidにはCredential Manager(AndroidX Credentials)、iOSにはSwift Package Manager経由のGIDSignIn SDKを使用することを推奨します。Credential ManagerはGoogleがサポートする最新のAPIで、Google Sign-In、Passkeys、パスワードログインを単一のインターフェースに統合します。非推奨のGoogleSignInClient(com.google.android.gms:auth)はもう推奨されていません。
ID Tokenはユーザー情報(名前、メール、一意のID)を含むJWTです。アプリのサーバー側での認証に使用されます。Access TokenはGoogle API(Google Drive、Calendar)にアクセスするための不透明な文字列です。ID Tokenの有効期限は1時間で、Access Tokenも1時間ですが、Refresh Tokenを通じて更新できます。
技術的には可能ですが、安全ではありません。クライアント側だけでID Tokenを検証すると、攻撃者がアプリを逆コンパイルして検証ロジックを抽出する可能性があります。Googleの公開鍵を使用したサーバー側の検証により、トークンが実際にGoogleによって発行され、偽造されていないことが保証されます。サーバーのないアプリの場合は、Firebase Authenticationを使用してください。
エラー12501(SIGN_IN_FAILED)は、アプリのSHA-1証明書がGoogle Cloud Consoleで指定されたものと一致しない場合に発生します。解決策:デバッグ証明書(Android Studioから)とリリース証明書のSHA-1をコンソールに追加します。また、コンソールのパッケージ名がbuild.gradleと一致することを確認してください。変更後、反映には最大24時間かかる場合があります。
いいえ、Google Sign-InはGoogleサーバーと通信するためにインターネット接続が必要です。デバイスがオフラインの場合は、セッションキャッシュ機構を使用してください:ログイン成功後、トークンをEncryptedSharedPreferencesに保存し、次回起動時に有効性を確認します。ネットワークがない場合は、保存されたデータを表示し、後でログインするよう提案します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。