JWT 인증: 로그인과 갱신
액세스 토큰과 갱신 토큰 흐름, httpOnly 쿠키와 인터셉터를 이용한 자동 갱신을 다룹니다.
JWT 인증: 로그인과 갱신은(는) CoddyKit의 무료 Vue Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Vue Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Vue Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
액세스 및 갱신 token 모델
견고한 JWT 방식은 두 개의 token을 사용합니다. 하나는 수명이 짧은 액세스 token(몇 분)으로 모든 API 요청에 함께 보내고, 다른 하나는 수명이 긴 갱신 token(며칠)으로 새 액세스 token을 발급할 때만 사용합니다. 이렇게 하면 액세스 token이 유출되더라도 노출 범위를 제한할 수 있습니다.
JWT 플러그인 등록
Fastify에서 @fastify/jwt를 등록하고 강력한 비밀 키를 제공합니다. 그러면 앱과 요청 객체에 서명 및 검증 도우미가 추가됩니다.
import jwt from '@fastify/jwt'
await app.register(jwt, {
secret: process.env.JWT_SECRET
})로그인 경로
POST /auth/login은 자격 증명을 검증한 다음 두 token을 모두 발급합니다. 평문 비밀번호를 저장하지 말고 해시(bcrypt/argon2)와 비교해야 합니다.
app.post('/auth/login', async (req, reply) => {
const { email, password } = req.body
const user = await findUser(email)
if (!user || !(await verifyHash(password, user.hash))) {
return reply.code(401).send({ error: 'Invalid credentials' })
}
// ... sign tokens (next scene)
})액세스 token에 서명하기
사용자 식별자와 최소한의 클레임을 담은 수명이 짧은 액세스 token에 서명합니다. 만료 시간은 짧게 유지해야 합니다(예: 15분).
const accessToken = app.jwt.sign(
{ sub: user.id, role: user.role },
{ expiresIn: '15m' }
)갱신 token에 서명하기
구별되는 페이로드 표시자를 포함하거나 별도의 비밀 키를 사용해 수명이 긴 갱신 token에 서명합니다. 이 token은 갱신 엔드포인트에서만 사용합니다.
const refreshToken = app.jwt.sign(
{ sub: user.id, type: 'refresh' },
{ expiresIn: '7d' }
)httpOnly 쿠키에 갱신 token 저장하기
갱신 token은 httpOnly, SameSite, Secure 쿠키에 저장합니다. JavaScript가 읽을 수 없으므로 XSS를 통한 탈취를 줄일 수 있고, 브라우저가 갱신 엔드포인트로 자동 전송합니다.
reply.setCookie('refreshToken', refreshToken, {
httpOnly: true,
sameSite: 'strict',
secure: true, // HTTPS only
path: '/auth/refresh',
maxAge: 60 * 60 * 24 * 7
})본문으로 액세스 token 반환하기
액세스 token은 JSON 응답 본문으로 반환합니다. Vue 앱은 이를 localStorage가 아닌 메모리에 보관하고 API 요청에 추가합니다. 갱신 token은 본문에 절대 나타나지 않습니다.
return reply.send({
accessToken,
user: { id: user.id, name: user.name }
})
// refreshToken is only in the httpOnly cookie액세스 token을 localStorage에 저장하지 않는 이유
localStorage는 모든 스크립트에서 읽을 수 있으므로 XSS 취약점이 있으면 그 안의 token을 탈취할 수 있습니다. 액세스 token을 JS 메모리에 보관하고 갱신 token을 httpOnly 쿠키에 저장하면 XSS의 피해 범위를 줄일 수 있습니다.
갱신 경로
POST /auth/refresh는 쿠키에서 갱신 token을 읽고 검증한 뒤 새 액세스 token을 발급합니다. 새 액세스 token은 본문으로 반환합니다.
app.post('/auth/refresh', async (req, reply) => {
const token = req.cookies.refreshToken
if (!token) return reply.code(401).send()
try {
const payload = app.jwt.verify(token)
const accessToken = app.jwt.sign(
{ sub: payload.sub }, { expiresIn: '15m' }
)
return reply.send({ accessToken })
} catch {
return reply.code(401).send({ error: 'Invalid refresh' })
}
})경로 보호하기
Authorization 헤더에서 액세스 token을 검증하는 preHandler를 추가합니다. @fastify/jwt의 request.jwtVerify()는 유효하지 않거나 만료된 token에서 예외를 발생시키고 401을 반환합니다.
app.get('/api/me', {
preHandler: async (req, reply) => {
try { await req.jwtVerify() }
catch { reply.code(401).send({ error: 'Unauthorized' }) }
}
}, async (req) => getProfile(req.user.sub))로그아웃: 쿠키 삭제
로그아웃하면 갱신 쿠키가 삭제되어 더 이상 액세스 token을 발급할 수 없습니다. 더 강력한 보장이 필요하다면 서버에서도 갱신 token을 추적하고 폐기해야 합니다(거부 목록 또는 순환 방식).
app.post('/auth/logout', async (req, reply) => {
reply.clearCookie('refreshToken', { path: '/auth/refresh' })
return reply.send({ ok: true })
})빠른 확인
JWT 인증에 대한 이해도를 확인해 보세요.
복습
JWT 로그인과 갱신을 배웠습니다:
- 수명이 짧은 액세스 token과 수명이 긴 갱신 token
POST /auth/login은 자격 증명을 검증하고 두 token에 서명합니다- 갱신 token은 httpOnly SameSite Secure 쿠키에 저장합니다
- 액세스 token은 본문으로 반환하고 JS 메모리에 보관합니다
POST /auth/refresh는 쿠키에서 새 액세스 token을 발급합니다
AI 튜터와 함께 HTML을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 42
- 레슨
- 156
자주 묻는 질문
“JWT 인증: 로그인과 갱신” 강의는 무료인가요?
네 — “JWT 인증: 로그인과 갱신” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Vue Academy 강의 전체를 잠금 해제할 수 있습니다. Vue Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“JWT 인증: 로그인과 갱신”에서 뭘 배우나요?
액세스 토큰과 갱신 토큰 흐름, httpOnly 쿠키와 인터셉터를 이용한 자동 갱신을 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 Vue Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Vue Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Vue Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“JWT 인증: 로그인과 갱신” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Vue Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Vue Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.