체인의정석

Next.js) 프론트엔드에서의 JWT 관리 본문

개발/frontend

Next.js) 프론트엔드에서의 JWT 관리

체인의정석 2025. 4. 25. 17:08
728x90
반응형

1. JWT 저장 위치
JWT는 로컬 스토리지, 세션 스토리지에 사용이 가능한데 세션 스토리지에 사용하는 것이 주기가 더 짧음

개발자 도구의 Applicaion에 들어가면 세션 스토리지에 발급된 jwt를 확인할 수 있다.

2. 로그인시 JWT 발급


백엔드에 JWT에 대한 검증 로직 및 각 API에서 JWT의 role을 보고 처리하는 로직을 만들어 준다.
그러나 프론트엔드에서도 jwt의 기간이 만료되거나 유효한 형태인지 정도의 체크는 해주고 유효하지 않을 경우 로그인 화면으로 보내서 jwt를 재발급을 요청하는 과정이 필요하다.

interface JWTHeader {
    alg: string;
    typ: string;
}

interface JWTPayload {
    wallet_address: string;
    role: "example1" | "example2"; // 백엔드 기준
    exp: number;                     // Unix timestamp (in seconds)
    iat: number;
    iss: string;
    [key: string]: unknown; // 확장성을 위해
}

export function parseJWT(token: string): { header: JWTHeader; payload: JWTPayload } | null {
    try {
        const [headerB64, payloadB64] = token.split('.');
        const header = JSON.parse(atob(headerB64));
        const payload = JSON.parse(atob(payloadB64));
        return { header, payload };
    } catch {
        return null;
    }
}

export function isJWTExpired(token: string): boolean {
    const parsed = parseJWT(token);
    if (!parsed || !parsed.payload.exp) return true;

    const exp = parsed.payload.exp * 1000; // JS는 ms 단위
    return Date.now() > exp;
}

 

 

3. axios 를 보낼 때 header에 session storage의 JWT를 넣어준 후 api 요청 진행

import axios from "axios";

const axiosInstance = axios.create({
    baseURL: process.env.API_URL || "http://localhost:3001",
    withCredentials: true,
});

axiosInstance.interceptors.request.use((config) => {
    const token = typeof window !== "undefined" ? sessionStorage.getItem("jwt") : null;
    if (token) {
        config.headers["Authorization"] = `Bearer ${token}`;
    }
    return config;
});

export default axiosInstance;

요청을 보낼 때는 다음과 같이 보냄

        const data = {
            wallet_address: toLowerAddress(walletAddress),
            nick_name: userName,
            team: teamName,
        };
        await axiosInstance.post("/example/register", data);

 

다만 로그인시 필요한 API나 healt같은 api는 jwt인증을 하지 않고서도 호출이 가능해야하기 때문에 다음과 같이 따로 인스턴스를 만들어서 구분하여 사용해주어야 한다.

const axiosPublicInstance = axios.create({
    baseURL: process.env.API_URL",
});

 

728x90
반응형
Comments