LoginSignup
4
3

More than 1 year has passed since last update.

React(Javascript & Typescript)でgoogleアカウント認証を行うカスタムhookを作成する

Posted at

reactでgoogleアカウント認証を実装しする必要があったので、作成したコードを備忘録として残します。
gapiのauth2から返ってくるtokenIDを管理するためのカスタムhookを作成しました。

Javascript版reactでの実装

import { useEffect, useState } from 'react';

const useGoogleAuth = () => {
  const [isSignedIn, setIsSignedIn] = useState(null);
  const [authInstance, setAuthInstance] = useState(null);
  const [tokenId, setTokenId] = useState(null);

  useEffect(() => {
    const initAuth = async () => {
      const gapi = window.gapi;

      await gapi.load('auth2', async () => {
        const auth2 = await gapi.auth2.init({
          client_id: 'YOUR_CLIENT_ID',
        });

        setAuthInstance(auth2);

        const isSignedIn = auth2.isSignedIn.get();
        setIsSignedIn(isSignedIn);

        if (isSignedIn) {
          const user = auth2.currentUser.get();
          const token = user.getAuthResponse().id_token;
          setTokenId(token);
        }
      });
    };

    initAuth();
  }, []);

  const handleSignIn = async () => {
    const user = await authInstance.signIn();
    setIsSignedIn(true);

    const token = user.getAuthResponse().id_token;
    setTokenId(token);
  };

  const handleSignOut = async () => {
    await authInstance.signOut();
    setIsSignedIn(false);
    setTokenId(null);
  };

  return {
    isSignedIn,
    tokenId,
    handleSignIn,
    handleSignOut,
  };
};

export default useGoogleAuth;

以上がReactでGoogleアカウント認証を実装するためのカスタムフックです。このフックを使用することで、gapiのauth2から返ってくるtokenIDを管理できます。

このフックを使用するには、以下のように呼び出します。

import useGoogleAuth from './useGoogleAuth';

const MyComponent = () => {
  const { isSignedIn, tokenId, handleSignIn, handleSignOut } = useGoogleAuth();

  // 以下、必要な処理を記述
};

このフックを使用することで、isSignedInプロパティでサインインしているかどうかを確認し、tokenIdプロパティで取得したトークンIDを管理することができます。また、handleSignInとhandleSignOut関数を使用して、サインインおよびサインアウトのアクションをトリガーすることができます。

TypeScriptでの実装

同じ実装をTypeScriptで行うと下記のようになります。

import { useEffect, useState } from 'react';

interface IGoogleAuth {
  isSignedIn: boolean | null;
  tokenId: string | null;
  handleSignIn: () => Promise<void>;
  handleSignOut: () => Promise<void>;
}

const useGoogleAuth = (): IGoogleAuth => {
  const [isSignedIn, setIsSignedIn] = useState<boolean | null>(null);
  const [authInstance, setAuthInstance] = useState<gapi.auth2.GoogleAuth | null>(
    null
  );
  const [tokenId, setTokenId] = useState<string | null>(null);

  useEffect(() => {
    const initAuth = async () => {
      const gapi = window.gapi;

      await gapi.load('auth2', async () => {
        const auth2 = await gapi.auth2.init({
          client_id: 'YOUR_CLIENT_ID',
        });

        setAuthInstance(auth2);

        const isSignedIn = auth2.isSignedIn.get();
        setIsSignedIn(isSignedIn);

        if (isSignedIn) {
          const user = auth2.currentUser.get();
          const token = user.getAuthResponse().id_token;
          setTokenId(token);
        }
      });
    };

    initAuth();
  }, []);

  const handleSignIn = async () => {
    const user = await authInstance?.signIn();
    setIsSignedIn(true);

    const token = user?.getAuthResponse().id_token;
    setTokenId(token || null);
  };

  const handleSignOut = async () => {
    await authInstance?.signOut();
    setIsSignedIn(false);
    setTokenId(null);
  };

  return {
    isSignedIn,
    tokenId,
    handleSignIn,
    handleSignOut,
  };
};

export default useGoogleAuth;

このフックを使用するには、以下のように呼び出します。

import useGoogleAuth from './useGoogleAuth';

const MyComponent = () => {
  const { isSignedIn, tokenId, handleSignIn, handleSignOut } = useGoogleAuth();

  // 以下、必要な処理を記述
};

TypeScriptを使用することで、より安全で保守性の高いコードを書くことができますね。

参考になる書籍など

TypeScriptとReact/Next.jsでつくる実践Webアプリケーション開発
モダンJavaScriptの基本から始める React実践の教科書
React(v18)完全入門ガイド|Hooks、Next.js、Redux、TypeScript

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3