티스토리 뷰
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 23 - RAG 기반 검색 및 문서 조회 기능 구현
octo54 2025. 2. 27. 16:31🚀 FastAPI 기반 로컬 LLM + RAG 챗봇 – 4.1.1 JWT 기반 인증 방식
이번 글에서는 JWT(JSON Web Token) 기반 인증 방식의 개념과 구조, 그리고 Next.js에서 JWT를 활용하는 방법을 다룹니다.
✅ JWT의 기본 개념을 이해하고, Access Token과 Refresh Token의 차이를 학습합니다.
✅ Next.js API Route에서 JWT 인증을 구현하는 방법을 실습합니다.
📌 1. JWT란?
✅ 1.1 JWT 개념 및 구조
JWT(JSON Web Token)는 토큰 기반 인증 방식으로, 클라이언트와 서버 간 인증 정보를 안전하게 주고받을 수 있도록 설계되었습니다.
📌 JWT는 3가지 주요 구성 요소로 이루어져 있습니다.
Header.Payload.Signature
예제 JWT 토큰:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywiZXhwIjoxNjg2NzI2MDAwfQ.9m2nH0qyxm1t0lKf9Ow3K4BZc2YnTzF7T8wMxBHY8lA
각 부분의 역할은 다음과 같습니다.
구성 요소 설명
Header | 토큰의 타입(JWT) 및 암호화 알고리즘 (HS256, RS256 등) |
Payload | 사용자 ID, 권한, 토큰 만료 시간(exp) 등 포함 |
Signature | 토큰의 위변조 방지를 위한 서명 |
✅ JWT는 서버에서 클라이언트에게 발급한 후, 클라이언트가 API 요청 시 포함하여 인증을 수행하는 방식입니다. 🚀
📌 2. Access Token vs Refresh Token
JWT를 활용한 인증에서는 Access Token과 Refresh Token을 구분하여 사용합니다.
구분 설명 만료 시간 저장 위치
Access Token | API 요청 시 사용되는 인증 토큰 | 짧음 (5~30분) | 메모리 or HTTP Only 쿠키 |
Refresh Token | Access Token이 만료되었을 때 재발급하는 토큰 | 김 (7일~30일) | 데이터베이스 or Secure Cookie |
✅ Access Token은 보안상 짧은 유효 기간을 가지며, Refresh Token을 활용하여 갱신합니다. 🚀
📌 3. Next.js에서 JWT 인증 구현하기
✅ 3.1 JWT 토큰 생성하기
📌 Step 1: JWT 라이브러리 설치
npm install jsonwebtoken bcryptjs
📌 Step 2: JWT 유틸리티 함수 생성 (app/utils/jwt.ts)
import jwt from "jsonwebtoken";
const SECRET_KEY = process.env.JWT_SECRET || "your_secret_key";
export const generateToken = (userId: string) => {
return jwt.sign({ userId }, SECRET_KEY, { expiresIn: "15m" });
};
export const verifyToken = (token: string) => {
try {
return jwt.verify(token, SECRET_KEY);
} catch (error) {
return null;
}
};
✅ 이제 JWT를 생성하고 검증하는 기능을 구현했습니다! 🚀
✅ 3.2 Next.js API Route에서 JWT 로그인 구현
📌 app/api/auth/login/route.ts (로그인 시 JWT 발급)
import { NextResponse } from "next/server";
import { generateToken } from "@/app/utils/jwt";
export async function POST(req: Request) {
const { username, password } = await req.json();
// (실제 서비스에서는 데이터베이스에서 사용자 검증 필요)
if (username !== "admin" || password !== "1234") {
return NextResponse.json({ error: "Invalid credentials" }, { status: 401 });
}
const token = generateToken(username);
return NextResponse.json({ token });
}
✅ 이제 /api/auth/login 엔드포인트를 통해 JWT를 발급할 수 있습니다! 🚀
✅ 3.3 Next.js API Route에서 JWT 검증하기
📌 app/api/protected/route.ts (JWT 검증 및 보호된 API)
import { NextResponse } from "next/server";
import { verifyToken } from "@/app/utils/jwt";
export async function GET(req: Request) {
const authHeader = req.headers.get("authorization");
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const token = authHeader.split(" ")[1];
const decoded = verifyToken(token);
if (!decoded) {
return NextResponse.json({ error: "Invalid token" }, { status: 403 });
}
return NextResponse.json({ message: "Protected data", user: decoded });
}
✅ 이제 /api/protected 엔드포인트를 호출하면 JWT 인증을 거쳐야 합니다! 🚀
✅ 3.4 클라이언트에서 JWT 로그인 요청하기
📌 app/components/Login.tsx (JWT 로그인 요청)
"use client";
import { useState } from "react";
export default function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [token, setToken] = useState("");
const handleLogin = async () => {
const res = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password }),
});
const data = await res.json();
if (res.ok) {
setToken(data.token);
alert("로그인 성공! 토큰이 저장되었습니다.");
} else {
alert("로그인 실패: " + data.error);
}
};
return (
<div>
<input type="text" placeholder="Username" onChange={(e) => setUsername(e.target.value)} />
<input type="password" placeholder="Password" onChange={(e) => setPassword(e.target.value)} />
<button onClick={handleLogin}>로그인</button>
{token && <p>발급된 JWT: {token}</p>}
</div>
);
}
✅ 이제 클라이언트에서 로그인 요청을 보내면 JWT를 받아 인증할 수 있습니다! 🚀
📌 4. JWT 보안 강화 Best Practices
- ✅ HTTP Only 쿠키 사용 → 클라이언트에서 직접 접근할 수 없도록 설정
- ✅ Refresh Token을 활용한 자동 재발급 → Access Token이 만료되었을 때 새로운 토큰 발급
- ✅ JWT 서명 키를 안전하게 관리 (.env 파일 사용)
- ✅ JWT 토큰의 유효 기간을 짧게 설정 (15~30분)
- ✅ OAuth와 조합하여 보안 강화 (Google, GitHub 로그인)
📌 5. 결론 및 다음 단계
✅ JWT의 개념과 구조를 학습했습니다.
✅ Access Token과 Refresh Token의 차이를 이해했습니다.
✅ Next.js API Route에서 JWT 인증을 구현하고, 클라이언트에서 로그인 요청하는 방법을 실습했습니다.
✅ 보안을 강화하기 위한 Best Practices를 정리했습니다.
🚀 다음 글에서는 "4.1.2 NextAuth.js를 활용한 OAuth 로그인"을 진행합니다!
'project > 로컬 LLM + RAG 기반 AI 채팅봇 만들기' 카테고리의 다른 글
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 25 - 검색 성능 모니터링 및 개선 (0) | 2025.02.27 |
---|---|
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 24 - 검색된 문서와 LLM 응답 결합 (0) | 2025.02.27 |
🚀 FastAPI 기반 로컬 LLM + RAG 챗봇 – React Query와 Zustand의 차이점 및 활용법 (0) | 2025.02.27 |
🚀 FastAPI 기반 로컬 LLM + RAG 챗봇 – Zustand를 활용한 전역 상태 관리 (0) | 2025.02.27 |
🚀 FastAPI 기반 로컬 LLM + RAG 챗봇 – Next.js에서의 상태 관리 개요 (0) | 2025.02.27 |
- Total
- Today
- Yesterday
- 챗봇개발
- Python
- 프론트엔드
- til
- nextJS
- llm
- babel
- 웹개발
- PostgreSQL
- 페이지
- Docker
- 백엔드
- Webpack
- Project
- 로컬LLM
- Next.js
- github
- Ktor
- nodejs
- rag
- LangChain
- Page
- fastapi
- 리액트
- 개발블로그
- 관리자
- kotlin
- AI챗봇
- REACT
- 백엔드개발
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |