Expo Google認証コード解説

このコードはExpo(React Native)でGoogleログイン機能を実装したものです。

インポート部分

import * as Google from "expo-auth-session/providers/google";
import * as WebBrowser from "expo-web-browser";
import { useCallback, useEffect, useState } from "react";
import { Button, StyleSheet, Text, View } from "react-native";
  • expo-auth-session/providers/google: Google認証用のフックとユーティリティ
  • expo-web-browser: 認証用のWebブラウザセッション管理
  • React標準のフックとReact Nativeのコンポーネント

初期設定

WebBrowser.maybeCompleteAuthSession();

認証セッションが完了していない場合に完了させる処理です。アプリがバックグラウンドから復帰した際などに必要となります。

State管理

const [token, setToken] = useState("");
const [user, setUser] = useState<any>(null);
  • token: 認証で取得したアクセストークンを保存
  • user: ログインしたユーザーの情報(名前、メールアドレスなど)を保存

Google認証設定

const [request, response, promptAsync] = Google.useAuthRequest({
  clientId: process.env.EXPO_PUBLIC_GOOGLE_CLIENT_ID!,
  scopes: ["openid", "profile", "email"],
});
  • clientId: GoogleのOAuth2.0クライアントID(環境変数から取得)
  • scopes: 取得する権限の範囲
    • openid: OpenID Connect用の基本情報
    • profile: プロフィール情報(名前、写真など)
    • email: メールアドレス
  • 戻り値:
    • request: 認証リクエストの設定情報
    • response: 認証結果
    • promptAsync: 認証画面を表示する関数

ユーザー情報取得関数

const getUserInfo = useCallback(async () => {
  try {
    const response = await fetch(
      "https://www.googleapis.com/userinfo/v2/me",
      {
        headers: { Authorization: `Bearer ${token}` },
      }
    );
    const user = await response.json();
    console.log(user);
    setUser(user);
  } catch (error) {
    // Add your own error handler here
  }
}, [token]);

アクセストークンを使ってGoogle People APIからユーザー情報を取得する関数です。

  • useCallbackでメモ化してパフォーマンスを向上
  • AuthorizationヘッダーにBearerトークンを設定
  • 取得したユーザー情報をstateに保存

認証完了時の処理

useEffect(() => {
  if (response?.type === "success" && response.authentication) {
    setToken(response.authentication.accessToken);
    getUserInfo();
  }
}, [getUserInfo, response, token]);

認証レスポンスを監視し、成功時にトークンを保存してユーザー情報を取得します。

  • response.type === "success": 認証が成功したかチェック
  • response.authentication: 認証情報が存在するかチェック
  • アクセストークンを取得してstateに保存
  • ユーザー情報取得関数を実行

UI部分

return (
  <View style={styles.container}>
    {user === null ? (
      <Button
        title="Sign in with Google"
        disabled={!request}
        onPress={() => {
          promptAsync();
        }}
      />
    ) : (
      <Text style={styles.text}>{user.name}</Text>
    )}
  </View>
);
  • ユーザーがログインしていない場合:「Sign in with Google」ボタンを表示
  • ログイン済みの場合:ユーザーの名前を表示
  • ボタンはrequestが準備できるまで無効化

処理の流れ

  1. 初期表示: 「Sign in with Google」ボタンが表示される
  2. ボタンクリック: promptAsync()でGoogleログイン画面が開く
  3. 認証処理: ユーザーがGoogleアカウントでログイン
  4. 認証成功: アクセストークンを取得
  5. ユーザー情報取得: トークンを使ってGoogle APIからユーザー情報を取得
  6. 表示更新: ユーザー名が画面に表示される

必要な設定

このコードを動作させるには以下の設定が必要です:

  1. Google Cloud ConsoleでOAuth2.0クライアントIDを作成
  2. 環境変数EXPO_PUBLIC_GOOGLE_CLIENT_IDを設定
  3. 必要なパッケージのインストール:
    expo install expo-auth-session expo-crypto expo-web-browser