Balbas Code

GoogleのOAuth認証で使用するuseridを取得する

公開日: 2024-10-31 20:20:23
更新日: 2024-11-01 12:53:56

本日はデータを引き継ぐ際に使用するGoogleアカウントの連携について書いていきます。

いろんなアプリのデータ引き継ぎとして実装されていたものを見てはいたものの、実際に仕様としてどのようになっているのかはわからなかったので、記事にしようと思います。
流れとしては
GoogleやApple、Yahoo、Xなどのさまざまな認証方法をよく見かけます。
こちらはそれぞれの会社のアカウントの公式フォームでログインするとAPIを通じてTokenが返ってきます。

返ってくるToken
google_oath

こちらをデコードすると
・ユーザー名
・メールアドレス
・ユーザーID (googleのユーザーIDではなく、認証に使う数字のみの値)
・トークンの有効期限

などが取得できます。
google_oathgoogle_oath


準備
まずはGoogle上の設定が必要になるので設定していきます。

OAuthクライアントIDの作成
google_oath


この中で名前やバンドルID、AppStoreID(数字のみの値)、チームIDの値を入力します。

google_oath
・赤枠のチェックはFirebaseを使用していたらチェックして、使用していなければチェックは不要です。
・チームIDはAppStoreConnectではなくAppleDeveloperのメンバーシップにあります。
google_oath


作成が完了したら、.plistファイルなるものをダウンロードしておきます。

google_oath
google_oath
こちらはXcodeのルートディレクトリに配置します。

google_oath

クリックするとこちらの内容が表示されるのでinfo.plistの値に使います。
google_oath

info.plist


    <!-- Google Sign-In 用のURLスキーム -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.6246XXXXXXXX-XXXXXXgh25tkn</string> <!-- REVERSED_CLIENT_IDの値 -->
</array>
</dict>
</array>

<!-- Google Sign-In クライアントID -->
<key>GIDClientID</key>
<string>6246XXXXXXXX-XXXXXXgh25tkn.apps.googleusercontent.com</string> <!-- GoogleのクライアントIDを指定 -->



AppDelegate


import GoogleSignIn

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Google Sign-Inの初期設定
if let clientID = Bundle.main.object(forInfoDictionaryKey: "GIDClientID") as? String {
GIDSignIn.sharedInstance.configuration = GIDConfiguration(clientID: clientID)
} else {
print("Google Client IDが見つかりません")
}
return true
}
}

使用するために初期設定


Podfile


  pod 'GoogleSignIn'
pod 'JWTDecode'

Podfileには上記に2つが必要になります。


次はGoogleのサイト上でアプリの登録を行います。
google_oath
アプリでは
・ホームページ
・プライバシーポリシー
・利用規約
を入力する画面があるので、作成する必要があります。
後でテスト→公開に変更するときに審査があります。


スコープの選択
google_oath
メールアドレスやユーザー名やユーザーID (数字のみの値)プロフィール画像等を取得したいときは上記2つを選択
認証に使うユーザーIDのみ取得する場合は赤枠のopenidのみにチェックを入れればいいです。
openidは漏洩したとしても個人が特定できる値ではないので、認証のみに使う場合はこちらだけ取得したらいいです。



後はボタンに下記のコードを組み合わせてユーザーが端末にログインできたらユーザーIDが取得できます。


import GoogleSignIn           // Googleのサインイン用
import JWTDecode

// Googleサインイン処理
private func startGoogleSignIn() {
GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
if let error = error {
print("Googleサインインエラー: \(error)")
return
}

// IDトークンの取得
guard let idToken = signInResult?.user.idToken?.tokenString else {
print("IDトークンが取得できませんでした")
return
}

// トークンを処理 musictheater06@gmail.com
self.handleToken(idToken)
}
}

// トークンを処理する共通メソッド
func handleToken(_ token: String) {
do {
let jwt = try decode(jwt: token)

// ユーザー名、メールアドレス、一意の識別子の取得
let userName = jwt.claim(name: "name").string ?? "不明"
let userEmail = jwt.claim(name: "email").string ?? "不明"
let userId = jwt.claim(name: "sub").string ?? "不明"

print("ユーザー名: \(userName)")
print("メールアドレス: \(userEmail)")
print("ユーザーID: \(userId)")

// 有効期限(exp)を確認
if let expirationDate = jwt.expiresAt {
if expirationDate > Date() {
print("トークンは有効です。")
} else {
print("トークンの有効期限が切れています。")
}
} else {
print("有効期限がトークンに含まれていません。")
}

} catch {
print("トークンのデコードに失敗しました: \(error)")
}
}


ユーザーIDはアカウントに対する一意の値をGoogleが発行する値なので、こちらをユーザーマスタに紐づけておけば、新端末などで検索して、バックアップとして利用できます。
google_oath

今回使ってみてわかったことはスコープの設定次第では、ユーザーのメールアドレスまでは簡単に抜けてしまう。
こういうのを適当に「はい」→「はい」と選択していく自分としては恐ろしや恐ろしや。