[블로그][프론트엔드] 로그인 인증 로직 리팩토링 - Auth.js

2026.02.05. 10:27

1. 문제인식

BFF 처리를 하면서 미들웨어, 인증관리 문제가 폭증. 

구글 로그인 등은 구현이 잘 되어있지만 문제는 GIS 인증이라 BFF로 리팩토링 중에 터지는 문제가 계속 발생함. 

그 외 로그인 로직 역시 안정성이 너무 떨어지는 문제가 계속 발생 중. 

구글 제외 다른 로그인 기능도 추가하려다 보니 유지보수가 힘듬.

구글 코드만 하더라도 매우 지저분하여 유지보수를 할 생각이 안듬.

타입스크립트 확장성도 안좋음.

"use client";
import { api_env } from "@/lib/env";
import { googleLogin } from "./auth.client";
import axios from "axios";

export function initGoogleLogin(buttonEl: HTMLDivElement) {
  const script = document.createElement("script");
  script.src = "https://accounts.google.com/gsi/client";
  script.async = true;
  script.defer = true;
  //GIS 스크립트 로드

  script.onload = () => {
    //스크립트가 로드되면 onload 이벤트가 발생
    if (window.google) {
      window.google.accounts.id.initialize({
        
        client_id: api_env.GOOGLE_CLIENT_ID, // 구글에서 발급받은 클라이언트 ID(환경변수 처리)
        callback: async (res: CredentialResponse) => {
          //GIS 에서 지정한 로그인 성공 시 발급되는 JWT 토큰을 처리하는 콜백함수
          if (!res.clientId || !res.credential) return;
          const userData:ICredential = decodeJWT(res.credential);
          console.log("구글 로그인 응답: ", userData);

          try {

            await googleLogin(userData);

            window.location.replace("/");
          } catch (err : unknown) {
            if (axios.isAxiosError(err) && err.response) {
              alert("로그인 실패 : " + err.response.data);
            } else {
              alert("로그인 중 알 수 없는 에러가 발생했습니다.");
            }
          }
        },
      });
      window.google.accounts.id.renderButton(buttonEl, {
        // 버튼 렌더링 옵션
        type: "standard",
        size: "large",
      });
    }
  };
  document.head.appendChild(script); // 스크립트 추가
  return () => {
    document.head.removeChild(script); // 컴포넌트 언마운트 시 스크립트 제거
  };
}

// JWT 디코딩 함수 : 구글 제공
export function decodeJWT(token: string) {
  const base64Url = token.split(".")[1];
  const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
  const jsonPayload = decodeURIComponent(
    atob(base64)
      .split("")
      .map(function (c) {
        return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
      })
      .join("")
  );
  return JSON.parse(jsonPayload);
}

2. Auth.js 도입

찾다보니 라이브러리 중에 Auth.js라는 라이브러리가 있어서 해당 라이브러리로 마이그레이션함. 

auth.js 는 자체 토큰을 갖고 있고 내가 백엔드에서 발급한 토큰은 해당 토큰에 다시 담기는 구조.

CSR이나 SSR 시에도 해당 토큰에 접근하여 인증객체를 가져올 수 있음.