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