🛠️인증, 인가, JWT, 요청 캐싱
인증
: 신원 자체를 검사하는 것.
- 유저가 누구인지 확인하는 절차, 로그인
- 존재하는지 안하는지
인가
: 신원 검증된 유저가 특정 자원에 대한 접근 권한이 있는지 검사하는 것.
- 접근 권한이 있는지 없는지
🪄실패 시 HTTP status code
Bad request (400) = client가 서버에 보낸 요청에 포함된 데이터가 잘못되었을 때. ⇒ DTO에 알맞지 않은 request.
Unauthorized (401) = 인증에 실패했을 때 ⇒ 로그인 실패
Forbidden (403) = 인가에 실패했을 때 ⇒ 권한 없음
Not Found (404) = 해당 리소스를 찾을 수 없을 때 ⇒ 해당 id를 찾을 수 없을 때
Conflict (409) = 리소스를 생성하려는데, 이미 존재할 때
🪄성공 시 HTTP status code
OK (200) ⇒ GET, PUSH, PATCH, DELETE
Created (201) ⇒ POST
- Header에 userId를 넣는 게 잘못된 이유
- Header에 유저 id를 넣는 것 자체가 잘못됨
- userId가 노출되기 때문
- 유저 id가 노출되면 해당 유저인 척 요청을 보낼 수 있음. 근데 이걸 막을 순 없음
- 매우 비효율적. 매 요청마다 DB에 쿼리를 사용자가 실제로 존재하는지 검사하는 코드를 작성해야함.
📍HTTP Stateless
: 서버가 클라이언트 상태를 보존하지 않는 것.
- Connectionless(비연결성)
- 각 요청이 독립적으로 처리
- 요청에 맞는 응답을 보낸 후 연결을 끊음
- Stateless(무상태성)
- 이전 데이터를 유지하지 않음
- 요청 시마다 인증 필요
- 장점 : 서버의 확장성이 높다. → 서버에 상태를 저장하지 않으므로 서버 확장이 용이함.
- 단점 : 클라이언트가 데이터를 추가 전송해야 한다.
- RESTful → stateless
📍두 가지 인가 방식
1️⃣ 세션 기반
- 흐름
- 클라이언트 : 사용자가 로그인 화면에서 로그인을 함. → 로그인 정보인 id, password를 서버로 request
- 서버 : DB에 저장된 id, password와 입력받은 id, password를 비교
- 서버 : 일치 시 session ID 생성 후, session ID, 사용자 정보(id, 이름 등)를 세션 유효기간 등의 정보가 담긴 새로운 세션을 생성. → 이 세션을 서버의 메모리 혹은 세션 스토어에 저장
- 서버 : 생성한 session ID를 클라이언트에 header의 Set-Cookie로 전달.
- 클라이언트 : 서버로부터 전달받은 session ID를 클라이언트의 쿠키에 저장
- 클라이언트 : 서버로 전송하는 모든 요청에 session ID를 쿠키에 담아 전달
- 서버 : 클라이언트로부터 받은 session ID와 세션 스토어에 저장되어 있는 session ID 일치 여부 확인
- 서버 : 일치 시 해당 session ID에 연결된 세션 정보를 스토어에서 검색
- 서버 : 세션 정보를 활용해 해당 유저의 상태나 권한 확인 → 요청에 맞는 작업 수행.
- 장점
- 쿠키에 아무런 의미 없는 session ID 값이 저장되므로 쿠키 해석 불가능.
- 유저의 모든 정보들은 서버에서 관리하기 때문에 안전함. → 유저 ID를 숨길 수 있음.
- 단점
- DB를 사용하므로 느림.
- DB를 In-Memory로 사용할 수도 있음. → 확장성이 좋지 않음(서버 컴퓨터를 추가할 경우 각 서버 컴퓨터마다 세션 정보를 공유 해야 하는 한계)
2️⃣토큰 기반
- 흐름
- 서버가 클라이언트로부터 로그인 요청을 받음
- 유저의 로그인 정보가 유효하다면 서버에서 유저의 정보(userId)를 담아 토큰 생성 (토큰은 public함.)
- 이 토큰을 클라이언트에 반환
- 클라이언트는 서버에 모든 요청마다 토큰을 포함해 요청을 보냄
- 서버는 토큰을 뜯어 사용자의 정보를 확인하여 토큰을 검증하고, 요청에 응답
- 토큰 종류
- AccessToken : 유저의 기본적인 정보와 만료 시간 등을 담은 토큰
- RefreshToken : AccessToken이 만료되었을 때, 재발급을 위한 토큰
- 장점
- 세션과 달리 DB를 한번 덜 거치기 때문에 좀 더 빠름
- 세션과 달리 범용적으로 쓰일 수 있음. 확장성이 좋음
- 단점
- 세션과 달리 너무 많은 정보를 클라이언트가 보유하게 됨
- 인증 정보(userId)를 클라이언트에서 관리하기 때문에 취약함
📍JWT(Json Web Token)
- JWT는 3개의 부분으로 이루어짐.
- Header : 암호화에 사용되는 알고리즘 정보→ 토큰을 어떻게 verify 하는지
- Payload : 실제로 담을 데이터 → 발급 시간, 만료 시간, 토큰을 통해 공개하기 원하는 내용(userID, name 등)
- Signagture : Base64라는 인코딩 방식으로 인코딩한 Header와 Payload 그리고 SECRET CODE를 합친 값.
- Header랑 Payload는 인코딩만 되고, 따로 암호화되지 않음. ⇒ 누구나 JWT를 까서 Payload를 볼 수 있음.
- Signature는 SECRET KEY(서버에 존재)를 모르면 복호화 불가능. ⇒ SECRET KEY를 알지 못하는 이상 토큰을 조작할 수 없음.
- JWT는 만료 시간을 포함할 수 있어서 토큰의 유효성을 관리할 수 있음. ⇒ 보통 AccessToken = 3시간 / RefreshToken = 1달
📍Spring Interceptor
Spring은 HTTP Request, Response가 Controller로 전달되기 전, Controller에 나온 후 해당 HTTP Request, Response를 가로채서 특정 작업을 수행할 수 있는 Interceptor라는 기능 제공.
Interceptor
: 컨트롤러의 핸들러를 호출하기 전이나 후에 요청과 응답을 참조하거나 가공할 수 있는 일종의 필터 역할.
- 인증해주는 역할. user 인증 완료 시 맞는 객체를 controller로 전달해줌.
- preHandle() : 컨트롤러가 호출되기 전 실행. → 리턴 값이 true이면 해당 인터셉터 실행 후 핸들러에 접근하고, false인 경우 작업 중단.
- postHandle() : 컨트롤러 실행 후, view 생성 이전에 실행.
- aferCompletion() : 모든 작업이 완료된 후에 실행.
🪄JwtTokenProvider 역할
- 정보(userId)를 받아 해당 정보를 payload에 담아 jwt token을 발급
- jwt token을 받아 복호화해 정보(userId)를 반환
@RequestScope
: Request가 들어와서 Interceptor까지 유지되는 Bean
- cotroller에서는 유효하지 않음.
- AuthenticationContext를 controller까지는 못가져감
- authentication 패키지에 어노테이션을 생성해서 주입해줘야 함.→ArgumentResolver에서 supportParameter , resolveArgument 정의
- supportsParameter() : 어떤 어노테이션의 기능인지
- resolveArgument() : 해당 어노테이션의 실제 동작 정의
- → @AuthenticateUser User user
🪄AuthenticationInterceptor 클래스
- request에서 access token 추출
- token(jwt)에서 payload(userId) 추출
- userId를 통해 User 검증, user 추출
- AuthenticationContext에 user저장.
Cookie
: 서버에 의해 사용자에 저장되는 정보 → 브라우저가 쿠키에 jwt를 저장
- key - value 형태
- key : AccessToken
- value : Bearer {Jwt}
Header: 서버와 클라이언트가 요청, 응답 시에 정보를 주고 받는 부분(userID 등)
Bearer
Authorization: Bearer {JWT Token}
'💻 백엔드개발 > 멋쟁이사자처럼 12기' 카테고리의 다른 글
git 명령어 (0) | 2024.10.30 |
---|---|
Cookie와 Header (0) | 2024.10.30 |
RDB, 데이터베이스 구축, JPA (0) | 2024.10.29 |
HTTP Request & Response, 예외처리 (0) | 2024.10.29 |
Spring MVC, 컨트롤러, 서비스, Lombok (0) | 2024.10.29 |