jwt의 개념과 역할 그리고 구현법에 대해 배웠다. 인증과 인가 절차는 모든 사이트에서 보안상 중요 요소이므로 앞으로 구현할 때 꼭 필요한 부분이라 유익했다. 잘 숙지하고 있어야겠다.
로그인 세션 - 인증과 인가
"로그인(=인증) 세션이 만료되었습니다"
우리는 사이트를 접속할 때 위의 문구를 많이 봤을 것이다. 이때, 인증은 무엇이며 세션이 만료되었다는 말을 무슨 의미인지 살펴보겠다.
인증과 인가
- 인증(=로그인) Authentication
: 관리자든 고객이든 인증을 통해서 사이트에 가입된 사용자라는 걸 증명하는 것 - 인가 Authorization
: 인증 후, 페이지 접근 권한 (다르게) 부여
예) 같은 사이트 내에 관리자 / 고객 에 따라 접근할 수 있는 페이지가 다르다.
쿠키와 세션 차이
- 쿠키와 세션 둘 다 로그인을 유지시켜주는 기능이라는 점에서 공통점이 있다.
쿠키
- 웹에서 서버와 클라이언트가 주고받는 데이터 중 하나
- 정확히는 생성은 웹 서버가 해서 웹 브라우저 주면, 브라우저가 자기 메모리에 저장해두고,
다음에 같은 웹서버 방문 시 쿠키 들고 요청하러 감
1) 사용자가 로그인 ➡️ 서버가 쿠키를 구워준다.
2) 사용자 ↔️ 서버가 쿠키를 핑퐁
- 장점
- 서버가 저장하지 않음 ➡️ 서버 저장 공간 아낄 수 있다
- http 특성 중 하나인 Stateless => RESTful하다(무상태성)
- 단점
- 보안에 취약하다.
세션
- 로그인이 되어 있는 상태를 말한다.
- 쿠키에 넣어서 보내기에 너무 중요한 내용은 서버가 가진 금고(세션)에 넣어두고 그 금고번호(세션ID)만 쿠키에 넣어서 통신
1) 사용자가 로그인 ➡️ 서버가 금고 만들어 정보 저장. 금고 번호를 준다.
2) 사용자 ↔️ 서버가 번호만 가지고 대화
- 장점
- 보안에 비교적 강하다.
- 단점
- 서버가 저장 ➡️ 서버 저장 공간을 쓴다
- Stateless 하지 않다. ➡️ RESTful하지 않음
JWT 개념, 특징
JSON Web Token
: JSON 데이터를 웹에서 안전하게 보관하는 토큰
- 토큰이 있으면 인증을 성공한다.
- 신분 증명 역할(권한 나눠가짐)
개념
- JSON 형태의 데이터를 안전하게 전송하기 위한 (웹에서 사용하는) 토큰
➡️ 토큰을 가진 사용자가 증명을 하기 위한 수단
cf. 토큰 : (인증용) 입장 가능한 유저 / (인가용) 관리자 권한&일반 유저 권한
장점
- 암호화가 되어 있어 보안에 강하다.
- HTTP 특징을 잘 따랐다: Stateless 하다.
- 서버가 상태를 저장하지 않는다. ➡️ 서버 부담 줄여줄 수 있다.
cf. 토큰을 발행하는 서버를 따로 만들어줄 수도 있음
구조(feat. jwt.io)
- 참조 링크 : https://www.jwt.io/
- 발행된 jwt 입력 시 decoded(복호화) 해서 내용을 확인하거나 encoded(암호화) 해주는 사이트
JSON Web Tokens - jwt.io
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).
www.jwt.io
- 구조 확인 가능
- 헤더/페이로드(정보/데이터)/베리파이 시그니처 를 각각 인코딩해서 . 으로 구분
- 헤더 - 토큰을 암호화하는 데 사용한 암호화 알고리즘(alg-hs256), 토큰 형태(typ-jwt)
- 페이로드 - JSON 형태, 사용자 정보(이름, 주소, ...비밀번호x)
- 시그니처 - 헤더와 페이로드 가 들어있다고 보증한 서명
➡️ 데이터(페이로드)가 바뀌면 시그니처 서명값도 바뀐다.
➡️ 기존에 서명한 데이터가 아니므로 받아주지 않는다.
➡️ JWT 보안이 높은 이유

JWT 인증-인가 절차
- 클라이언트가 로그인 요청 시 서버가 내부 로직을 확인한다.
- 서버가 JWT 즉, 토큰을 발행한다. 이때, 발행시점을 포함한다.
- 발행한 토큰을 쿠키에 동봉해 클라이언트에게 전달한다. (다음 요청 때 요구하기 위함)
- 클라이언트가 재로그인을 요청할 때 header에 JWT를 포함해 요청한다.
- 서버는 클라이언트가 보낸 JWT에서 서명(시그니처)이 일치 하는지 확인 후 일치하면 사이트 접속 인가를 해준다.
- 일치하지 않으면 403에러 블록을 던져준다.

JWT 구현해보기
jsonwebtoken 설치
-
npm i jsonwebtoken
토큰 발행
- jwt.sign(암호화할 페이로드 객체, 나만의 암호키)
var jwt = require('jsonwebtoken');
var token = jwt.sign({foo : 'bar'}, 'shhhhh');
// token 생성 = jwt 서명을 했다.(페이로드, 나만의 암호키) + SHA256
console.log(token)
토큰 검증 (복호화)
- jwt.verify(토큰, 나만의 암호키)
// 검증
// 만약 검증에 성공하면, 페이로드 값을 확인할 수 있음!
var decoded = jwt.verify(token, 'shhhhh');
console.log(decoded); // { foo: 'bar', iat: 1759329821 } // iat : issuedat - 발행시간
.env(environment : 환경 변수 '설정값')
개념
: 개발하다가 포트넘버, 데이터베이스 계정, 암호키...등등 외부에 유출되면 안 되는 중요한 환경 변수들을 따로 관리하기 위한 파일
cf. 깃허브에 올라가면 안되는 값
- .env 파일은 환경 변수 파일 -> 프로젝트 최상위 패키지에 존재
- 설치 : npm i dotenv
- .env 파일에 저장한 PRIVATE_KEY를 process.env.PRIVATE_KEY로 꺼낸 사용한다.

var dotenv = require('dotenv');
dotenv.config();
var token = jwt.sign({foo : 'bar'}, process.env.PRIVATE_KEY);
youtube에 jwt 적용해보기
- jsonwebtoken과 dotenv 모듈을 셋팅한다.
- 토큰 발행 : jwt.sign(암호화할 페이로드 객체, 나만의 암호키, 옵션)
- 옵션 객체{}를 열어 유효기간(expiredIn), 발행인(issuer) 설정 가능
- 제대로 옵션이 포함되었는지 확인하려면 jwt.io에서 토큰을 직접 넣어서 확인 가능하다.
- 서버가 클라이언트한테 token 발행할 때 쿠키에 동봉해서 보내준다.
// jwt 모듈
const jwt = require('jsonwebtoken')
// dotenv 모듈
const dotenv = require('dotenv')
dotenv.config();
if(loginUser && loginUser.pwd === pwd){
// token 발급 / 유효기간 설정
const token = jwt.sign({
email : loginUser.email,
name : loginUser.name
}, process.env.PRIVATE_KEY, {
expiresIn : '30m',
issuer : 'yj'
});
// 쿠키에 토큰 담기 - 토큰 변수에 토큰 담기
res.cookie("token", token, {
httpOnly : true
})
res.status(200).json({
message : `${loginUser.name}님 환영합니다.`,
})
}
else{
res.status(403).json({ // 인증 안됨
message : "아이디 또는 비밀번호가 일치하지 않습니다."
})
}
cookie 설정
쿠키에 jwt 값 담아주기
// 쿠키에 토큰 담기 - 토큰 변수에 토큰 담기
res.cookie("token", token)
cookie 설정 변경
- postman 쿠키 탭 컬럼에 Secure와 HttpOnly를 확인할 수 있다.
- Secure : https 환경인지 묻는 것
- https는 암호화된 페이지
- HttpOnly : 프론트엔드가 아니라 API 호출만 허락할건지 묻는 것 ➡️ true로 변경
- 브라우저에서 쿠키에 접근하는 보안공격을 방지하기 위함. ex> XSS 공격(프론트엔드 공격 : 웹 브라우저 js 접근 = 공격)
403 에러
- 권한을 허가하지 않을 때 보내는 상태코드 에러로 로그인 실패 시 403 에러 상태 코드를 보내준다.
※ gitignore 파일 만들기
.git init 폴더가 있는 프로젝트 최상위 루트에 .gitignore 파일을 만든다.
그 안에 버전관리에 포함하지 않을 파일을 패턴에 맞게 작성해 준다.
• 표준 Glob 패턴을 사용한다.
• 아무것도 없는 라인이나, "#"으로 시작하는 라인은 무시한다.
• 슬래시(/)로 시작하면 하위 디렉토리에 적용되지(Recursivity) 않는다.
• 디렉토리는 슬래시(/)를 끝에 사용하는 것으로 표현한다.
• 느낌표(!)로 시작하는 패턴의 파일은 무시하지 않는다.
<설정 예시>
# 확장자가 .a인 파일 무시
*.a
# 윗 라인에서 확장자가 .a인 파일은 무시하게 했지만 lib.a는 무시하지 않음
!lib.a
# 현재 디렉토리에 있는 TODO파일은 무시하고 subdir/TODO처럼 하위디렉토리에 있는 파일은 무시하지 않음
/TODO
# build/ 디렉토리에 있는 모든 파일 무시
build/
# doc/notes.txt 파일은 무시하고 doc/server/arch.txt 파일은 무시하지 않음
doc/*.txt
# doc 디렉토리 아래 모든 .pdf 파일 무시
doc/**/*.pdf
더 쉬운 셋팅법
gitignore.io라는 사이트에서 자신의 프로젝트에 꼭 맞는 .gitignore 파일을 자동으로 생성해준다.
운영체제, 개발 환경(IDE), 프로그래밍 언어 옵션을 넣으면 간단히 생성해준다.
https://www.toptal.com/developers/gitignore/
gitignore.io
Create useful .gitignore files for your project
www.toptal.com
'데브코스 웹풀스택 과정 > TIL' 카테고리의 다른 글
| 1106 프로그래밍 언어 기초문법 - C언어 포인터 (0) | 2025.11.05 |
|---|---|
| 1105 프로그래밍의 기본 원리 및 변수와 자료형 (0) | 2025.11.05 |
| 1001 express-validator 사용해 유효성 검사 / 검사결과 처리 미들웨어 분리 (0) | 2025.10.01 |
| 0930 타임 존(timezone) 설정, 디비 연동 및 쿼리 가져오기 (0) | 2025.09.30 |
| 0929 MySQL (mariadb) 날짜/시간 타입, FK컬럼 추가, auto_increment (0) | 2025.09.29 |