1) JWT (JSON Web Token)
: JSON 포맷을 이용해 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token
- 토큰의 한 종류
- 일반적으로 쿠키 저장소를 사용해 JWT 전달
JWT 사용 이유
1. 서버가 1대인 경우
- Session1이 모든 Client의 로그인 정보를 소유하고 있음.
2. 서버가 2대 이상인 경우
- 대용량 트래픽 처리를 하기 위해서는 서버가 두 대 이상 운영이 필요함.
- 중간에서 클라이언트의 요청을 밸런스있게 나눠주는 중간 역할을 하는 Load Balancer가 존재해
Session마다 다른 Client 로그인 정보를 가지고 있을 수 있음.
- ex
- Session1 : Client1, Client2, Client3
- Session2 : Client4
- Session3 : Client5, Client6
- ex
- 만약 Client 1의 로그인 정보를 가지고 있지 않은 Server2나 Server3에 API 요청을 하게되면 문제가 발생하지 않을까?
- 해결 방법
- Sticky Session: Client마다 요청 Server 고정
- 세션 저장소 생성하여 모든 세션을 저장
(아래의 세션 저장소 생성 참고)
- 해결 방법
세션 저장소 생성
- 외부의 Session storage 가 모든 Client의 로그인 정보를 소유하고 있다면 모든 서버에서 어떠한 클라이언트가 들어오든지 Session stroage에 물어보면 되기 때문에 모두 처리 가능.
JWT 사용
- 로그인 정보를 Server에 저장하는게 아닌, Client에 로그인 정보를 JWT로 암호화하여 저장한 후 모든 서버에서 토큰이 들어왔을 때 JWT 통해 인증/인가만 하면 됨.
- 모든 서버에서 동일한 비밀키를 가짐.
- Secret Key를 통한 암호화 / 위조 검증 (복호화 시)
- JWT 장/단점
- 장점
- 동시 접속자가 많을 때 서버 측 부하를 낮춰줌.
- DB같은 다른 storage랑 연결을 해서 체크하는 게 아니라, 동일한 값만 가지고 있으면 서버 자체에서 검증이 가능하기 때문에
- Client, Server가 다른 도메인을 사용할 때
- ex) 카카오 OAuth2 로그인 시 JWT Token 사용
- 동시 접속자가 많을 때 서버 측 부하를 낮춰줌.
- 단점
- 구현의 복잡도 증가
- JWT에 담는 내용이 커질수록 네트워크 비용 증가 (클라이언트 → 서버)
- JWT안에 많은 정보가 담겨있으면 JWT의 길이도 길어지게 되고, 이것이 HTTP 프로토콜에 담겨서 들어오는데, HTTP 프로토콜이 무겁고 용량이 클수록 네트워크 비용이 증가 함.
- 기 생성된 JWT를 일부만 만료시킬 방법이 없음
- 비밀키 유추시 JWT 조작 가능.
- 그러므로 JWT안에는 비밀번호 같이 민감한 데이터는 넣으면 안됨.
- 장점
- JWT 사용 흐름
- Client가 username, password로 로그인 성공 시
- ) 서버에서 "로그인 정보" → JWT로 암호화 (비밀키 사용)
- ) 서버에서 직접 쿠키를 생성해 JWT를 담아 Client 응답에 전달
- ) 브라우저 쿠키 저장소에 자동으로 JWT가 저장됨
- Client에서 JWT통한 인증 방법
- ) 서버에서 API 요청시마다 쿠키에 포함된 JWT를 찾아 사용
- ) Server
- Client가 전달한 JWT 위조 여부 검증 (비밀키 사용)
- JWT 유효기간이 지나지 않았는지 검증
- 검증 성공시
- JWT 에서 사용자 정보를 가져와 확인
ex; GET/api/products : JWT 보낸 사용자의 관심상품 목록 조회
- JWT 에서 사용자 정보를 가져와 확인
- Client가 username, password로 로그인 성공 시
- JWT 구조
- JWT는 누구나 복호화 가능하지만 비밀키가 없으면 JWT 수정 불가
- https://jwt.io/
- Header, Payload, Signature 부분으로 구성
- Payload에는 실제 유저의 정보가, Header와 Verify Signcature 부분은 암호화와 관련된 정보 양식이 들어있음.
Util 클래스
: 특정 매개 변수에 대한 작업을 수행하는 메서드들이 존재하는 클래스
- 다른 객체에 의존하지 않고 하나의 모듈로서 동작하는 클래스
- 어떠한 기능들을 가진 메서드들의 한 묶음(한 모듈)
ex; JWTUntil - JWT관련된 기능들을 가진 Class
@Enumerated
: EnumType을 DB 컬럼에 저장할 때 사용하는 annotation
- EnumType.STRING 옵션을 사용하면 Enum의 이름을 DB에 그대로 저장
- ex; USER(Authority.USER) → USER
패스워드 암호화
- 정보통신망법, 개인정보보호법 에 의해 비밀번호 암호화는 의무!
2) 패스워드 암호화
해커가 DB에서 패스워드 정보를 갈취하더라도 실제 암호를 알 수 없음. 그래서 복호화가 불가능한 단방향 암호 알고리즘 사용 필요
양방향 암호 알고리즘
- 암호화: 평문 → (암호화 알고리즘) → 암호문
- 복호화: 암호문 → (암호화 알고리즘) → 평문
단방향 암호 알고리즘
- 암호화: 평문 → (암호화 알고리즘) → 암호문
- 복호화: 불가
❓ 그럼 사용자는 로그인할 때 암호화된 패스워드를 기억해야 할까?
String Security라는 프레임워크에서 passwordEncoder가 제공하는 matches를 이용해 사용자가 입력한 비밀번호를 DB에 저장되어있는 암호화된 비밀번호와 비교해 일치여부를 확인해줌.
matches 메서드는 두 개의 인자를 받아 비교 후 일치여부 확인
➡️ 첫 번째 인자 - 원본 비밀번호 / 두 번째 인자 - 암호화된 비밀번호
'내일배움캠프(Sparta) > Spring' 카테고리의 다른 글
[Spring] Spring Security / Validation (1) | 2023.11.09 |
---|---|
[Spring] Filter (0) | 2023.11.09 |
[Spring] Authentication / Authorization / Cookie / Session (1) | 2023.11.08 |
[Spring] Bean (0) | 2023.11.08 |
[Spring] Spring Data JPA / JPA Auditing / Query Methods (0) | 2023.11.07 |