🔹 웹/모바일 앱에서 회원가입 & 로그인을 구현할 때, JWT(JSON Web Token) 기반 인증을 많이 사용함.
🔹 로그인 과정에서 Access Token과 Refresh Token이 발급됨.
🔹 이 두 개의 토큰을 관리하는 방식이 보안과 사용자 경험을 결정함.
1️⃣ 사용자가 이메일, 비밀번호 등을 입력
2️⃣ 서버에서 계정을 생성하고 비밀번호를 해싱(Hashing) 처리 (예: bcrypt)
3️⃣ 데이터베이스(DB)에 유저 정보 저장
4️⃣ 회원가입 성공 시 로그인 페이지로 리디렉트 또는 자동 로그인 처리
💡 해싱이 중요한 이유?
비밀번호를 그대로 DB에 저장하면 보안 위험 발생!
👉 해싱을 하면 복호화 불가능한 형태로 변환됨.
1️⃣ 사용자가 이메일 & 비밀번호 입력
2️⃣ 서버에서 해당 이메일이 DB에 있는지 확인
3️⃣ 입력한 비밀번호를 해싱하여 저장된 값과 비교
4️⃣ 로그인 성공 시 JWT 토큰 발급
5️⃣ 클라이언트(앱/브라우저)에 Access Token & Refresh Token 저장
🚨 보안적으로 위험한 방식!
❌ 비밀번호를 서버에서 평문(Plain Text)으로 비교하면 해킹 위험
✔ 해싱된 비밀번호 비교해야 안전
✔ 사용자의 인증 정보를 포함하는 토큰
✔ 토큰 자체에 정보가 들어있어 추가 DB 조회 없이 검증 가능
✔ 세션 기반 인증보다 확장성이 좋음
💡 JWT 구조
header.payload.signature
✅ Header → 토큰 타입 & 알고리즘 정보 (HS256, RS256)
✅ Payload → 유저 정보 (userId, role 등)
✅ Signature → 토큰 위변조 방지를 위한 서명
| Access Token | Refresh Token | |
|---|---|---|
| 역할 | API 요청 시 사용자 인증 | Access Token 만료 시 새로 발급 |
| 저장 위치 | 메모리, AsyncStorage, Secure Storage 등 | 주로 HttpOnly 쿠키 또는 Secure Storage |
| 유효 기간 | 짧음 (예: 15분~1시간) | 김 (예: 7일~30일) |
| 재발급 가능? | ❌ 불가능 | ✅ 가능 |
💡 왜 Access Token을 짧게 설정할까?
1️⃣ 사용자가 로그인하면 Access Token & Refresh Token을 발급
2️⃣ Access Token을 Authorization 헤더에 포함해 API 요청
3️⃣ 서버에서 토큰을 검증하고 요청을 처리
4️⃣ Access Token이 만료되면 Refresh Token으로 새 토큰 요청
5️⃣ Refresh Token이 만료되면 로그아웃 & 재로그인 필요
💡 보안 Tip!
1️⃣ 클라이언트에서 AsyncStorage(React Native) or localStorage(웹) 에 저장된 토큰 삭제
2️⃣ (필요한 경우) 서버에 Refresh Token을 보내서 무효화 요청
3️⃣ 로그인 화면으로 리디렉트
💡 Refresh Token 무효화해야 할 때?
import axios from "axios";
import AsyncStorage from "@react-native-async-storage/async-storage";
const API_URL = "baseUrl";
// 로그인 함수
export async function login(email: string, password: string) {
try {
const response = await axios.post(`${API_URL}/auth/login`, { email, password });
const { accessToken, refreshToken } = response.data;
// 토큰 저장
await AsyncStorage.setItem("accessToken", accessToken);
await AsyncStorage.setItem("refreshToken", refreshToken);
return true;
} catch (error) {
console.error("Login failed:", error);
return false;
}
}
// 로그아웃 함수
export async function logout() {
await AsyncStorage.multiRemove(["accessToken", "refreshToken"]);
}
✅ Access Token을 짧게 설정하고, Refresh Token으로 재발급
✅ Refresh Token은 서버에서 검증하고, 탈취되면 즉시 무효화
✅ 로그아웃 시 Refresh Token도 함께 삭제하여 보안 강화
✅ JWT 검증 시 DB 조회 없이 서버에서 처리하면 성능 최적화 가능