Membangun aplikasi web di era modern memerlukan pondasi yang kokoh. Framework modern memberikan fleksibilitas luar biasa bagi developer untuk menghadirkan fitur kompleks secara cepat tanpa mengabaikan aspek keamanan dan keandalan sistem.
Tahapan Implementasi & Walkthrough Kode
Berikut adalah langkah demi langkah teknis yang dapat Anda ikuti langsung pada codebase Anda:
Tahap 1: Penulisan Kode & Konfigurasi
//import useState and useEffect
import React, { useState, useEffect } from 'react';
//import useGoogleLogin and googleLogout
import { useGoogleLogin, googleLogout } from '@react-oauth/google';
//import axios
import axios from 'axios';
const App = () => {
// state access token
const [accessToken, setAccessToken] = useState(localStorage.getItem('accessToken'));
// state profile
const [profile, setProfile] = useState(JSON.parse(localStorage.getItem('profile')));
// function to handle login success
const handleLoginSuccess = (response) => {
// get access token from response
const token = response.access_token;
//set token in state
setAccessToken(token);
// set token in localStorage
localStorage.setItem('accessToken', token);
};
// function to handle login error
const handleLoginError = (error) => {
console.error('Login Failed:', error);
};
// function to login with google
const login = useGoogleLogin({
onSuccess: handleLoginSuccess,
onError: handleLoginError,
});
// function to fetch user profile
const fetchUserProfile = async (token) => {
try {
// call google api to fetch user profile
const res = await axios.get(
'https://www.googleapis.com/oauth2/v1/userinfo',
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
params: {
access_token: token,
},
}
);
// set profile in state
setProfile(res.data);
// set profile in localStorage
localStorage.setItem('profile', JSON.stringify(res.data));
} catch (error) {
console.error('Failed to fetch user profile:', error);
}
};
// useEffect to fetch profile when token exists
useEffect(() => {
if (accessToken && !profile) {
fetchUserProfile(accessToken); // fetch profile only if it's not already set
}
}, [accessToken, profile]);
// function to logout
const handleLogout = () => {
//call googleLogout
googleLogout();
//set state to null
setAccessToken(null);
setProfile(null);
//remove token and profile from localStorage
localStorage.removeItem('accessToken');
localStorage.removeItem('profile');
};
return (
<div className='container mt-5'>
<div className="row justify-content-center">
<div className="col-md-6">
<div className="card border-0 rounded shadow-sm">
<div className="card-header">
<h5 className="card-title mb-0">Google Login with React</h5>
</div>
<div className="card-body">
<div className='text-center'>
{profile ? (
<div>
<div className='text-center mb-3'>
<img src={profile.picture} className='rounded-circle bg-dark p-2 shadow' alt="User profile" />
</div>
<table className="table table-striped table-bordered">
<tbody>
<tr>
<td className='fw-bold'>Full Name</td>
<td>{profile.name}</td>
</tr>
<tr>
<td className='fw-bold'>Email Address</td>
<td>{profile.email}</td>
</tr>
</tbody>
</table>
<button className="btn btn-danger" onClick={handleLogout}>Log out</button>
</div>
) : (
<div className='text-center'>
<button className="btn btn-primary" onClick={() => login()}>Login with Google</button>
</div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default App;
Tahap 2: Penulisan Kode & Konfigurasi
//import useGoogleLogin and googleLogout
import { useGoogleLogin, googleLogout } from '@react-oauth/google';
Tahap 3: Penulisan Kode & Konfigurasi
<button className="btn btn-danger" onClick={handleLogout}>Log out</button>
Tahap 4: Penulisan Kode & Konfigurasi
// function to logout
const handleLogout = () => {
//...
}
Tahap 5: Penulisan Kode & Konfigurasi
//call googleLogout
googleLogout();
Tahap 6: Penulisan Kode & Konfigurasi
//set state to null
setAccessToken(null);
setProfile(null);
Tahap 7: Penulisan Kode & Konfigurasi
//remove token and profile from localStorage
localStorage.removeItem('accessToken');
localStorage.removeItem('profile');
Selalu gunakan pendekatan deklaratif, validasi input seawal mungkin di boundary layer, dan lakukan logging terstruktur untuk memudahkan observability ketika sistem dijalankan di lingkungan cloud produksi.
Kesimpulan
Dengan mengikuti langkah-langkah terstruktur di atas, implementasi modul Anda akan jauh lebih rapi, aman dari bug umum, serta siap diskalakan ke lingkungan produksi.
Nantikan artikel tutorial praktis lainnya seputar fullstack development, microservices, dan otomasi AI di Blog Engineering SiHubung. Selamat mencoba!