NestJS-Session, Jwt, Encryption

jaegeunsong97·2023년 11월 17일
0

NestJS

목록 보기
11/37

🖊️session, jwt

📍session

session

  • session : 유저 정보를 DB에 저장과 동시에 상태를 유지하는 것
  • 특징
    • session은 특수한 ID값 ex) adhb12jebdj 13urhfwosdfib
    • session은 서버에서 생성, client에서 Cookie를 통해 저장
    • 즉, client에서 request에 sessionId를 Header에 담아서 보내면 서버에서 DB를 조회해 누구인지 아는 것
  • 단점
    • DB를 매번 확인해야하는 번거로움
    • DB에 session을 저장해야하기 때문에 Horizontal Scaling(수평확장) 어려움
      • 왜냐하면 같은 사용자 session을 바라보도록 해야하기 때문에 resource가 많이 든다.
  • 장점
    • 서버에서 Data가 저장되기 때문에 client에 사용자 정보가 노출될 위험 X

session 생성 방식

  1. client => api Server
  • (id, pw)
  1. api Server 검증
  • (id, pw)
  1. 검증 통과, api Server => DB
  • DB에 (id, pw) 기반 세션 생성 및 저장
  1. api Server => client
  • 쿠키 전송

session 사용 방식

  1. client => api Server
  • 쿠키 전송
  1. api Server 검증
  • 쿠키 전송
  1. 검증 통과, api Server => DB
  • 쿠키를 기반으로 DB의 세션 조회
  1. DB => api Server
  • 유저 정보 응답
  1. api Server => DB
  • 데이터 요청
  1. DB => api Server
  • 데이터 응답

📍jwt

jwt

  • jwt : 유저 정보를 base64로 인코딩된 string된 값에 저장하는 것
  • 특징
    • JWT 구성
      • Header(base64 인코딩 됨)
      • Payload(base64 인코딩 됨)
      • Signature(base64 인코딩 됨)
    • 서버에서 생성 후 client에 저장
    • client가 JWT tokenId를 server에 넘기면, server는 매번 id와 pw로 구분하는 것이 아닌 token으로 구분
    • JWTDB에 저장 X, Signature로 검증, 검증시마다 DB접근 X
  • 단점
    • 정보가 Token에 담겨있어 정보유출 위험성이 있다.
  • 장점
    • 사용자 정보를 담을 DB가 필요없기 때문에 Horizontal Scaling 쉬움

jwt 생성 방식

  1. client => api Server
  • (id, pw)
  1. api Server 검증
  • (id, pw)
  • 세션처럼 DB를 만들어 저장하지 않는다. 단, 세션은 존재한다.
  1. api Server => client
  • token

jwt 사용 방식

  1. client => api Server
  • token
  1. api Server 검증
  • token
  1. api Server => DB
  • token으로 사용자 정보를 가져오고
  • 사용자 정보 기반으로 데이터 요청
  1. DB => api Server
  • 데이터 응답
  1. api Server => DB
  • 데이터 전송

📍비교

session

jwt

session과 jwt를 비교한 내용입니다.


🖊️jwt.io

https://jwt.io/

Header는 알고리즘과 토큰의 타입을 보여줍니다. 그리고 Payload는 데이터를 보여줍니다.

signature는 Base64로 인코딩된 Header와 Base64로 인코딩된 Payload를 합치고 secret키를 같이 합쳐서 SHA256으로 바꿔 만들어지게 됩니다.


🖊️Refresh token, Access token 이론

📍Refresh token & Access token

  • 특징
    • refresh와 access 모두 JWT 기반 토큰
    • access : api 요청시 검증용 토큰, 즉 인증 필요한 경우 header에 access 사용, 자주사용함
    • refresh : access 만료시 새롭게 발급받기 위함
    • access 짧게, refresh 길게
      • access 탈취시, 유효기간이 짧아 해킹 X
      • refresh의 경우 사용 빈도가 매우 낮아, 해킹 X

📍token 발급 과정

  1. client => api Server
  • (id, pw) => base64 encoded => token
  • HEADER {authorization: "Basic {token}"} 형태로 전송
  1. api Server
  • (id, pw) token
    • Basic 제거
    • base64 decoded
    • username:password 형태로 split
  1. api Server => client
  • 통과시 access token, refresh token 제공

📍refresh token 사용과정

  1. client => api Server
  • Access token 재발급 요청 URL
  • HEADER authorization: "Bearer {refresh token}"으로 보내기
  1. api Server
  • (id, pw) 검증
  1. api Server
  • access token 재발급
  1. api Server => client
  • 토큰 전송

📍access token 사용과정

  1. client => api Server
  • API 요청
  • HEADER authorization: "Bearer {access token}"으로 보내기
  1. api Server
  • (id, pw) 검증
  1. api Server => DB
  • 데이터 요청
  1. DB => api Server
  • 데이터 응답
  1. api Server => client
  • 데이터 응답

📍refreshing logic

access + refresh

  1. client => api Server
  • API 요청
  1. api Server
  • access token 검증
  1. api Server => client
  • access token 만료, 401
  1. client => api Server
  • access token 재발급 URL 요청
  • refresh token
  1. api Server
  • refresh token 검증
  1. api Server => client
  • access token 응답
  1. client => api Server
  • 새로운 access token으로 재요청
  1. api Server => DB
  • 데이터 요청
  1. DB => api Server
  • 데이터 응답
  1. api Server => client
  • 데이터 응답

🖊️encryption

암호화 알고리즘 종류는 다양합니다.

변경된 문자를 Hash라고 합니다. 그리고 Bcrypt를 많이 사용하는 이유는 느리기 때문입니다.

해커들을 Dictionary attack을 할 수 있습니다. 해커는 아래의 사진처럼 만들어두고 프로그램으로 계속 돌리는 것입니다.

그래서 bcrypt는 이를 방지하기 위해서 salt를 사용합니다. salt를 통해서 보호하는 것입니다. 그러면 완전 다른 문자가 나오게 됩니다.

만약 salt까지 털릴 수 있습니다. 그래서 앞서말한 bcrypt가 느린 이유가 나옵니다. 물론 털릴 수 있지만 salt와 DB를 털고 Dictionary 테이블을 만들기까지 너무나 오랜시간이 걸립니다. 따라서 사실상 불가능합니다. 그래서 bcrypt의 장점이됩니다. 원하는 만큼 느리게 만들 수 있습니다. 하지만 물론 사용자 또한 로그인을 할 때 오래걸리게 됩니다.

따라서 중간 지점을 찾아야 합니다.


🖊️질문사항

📍user 정보 확인시 DB 확인?

  • user정보 확인시
    • Session: DB를 반드시 확인해야하고(사용자 정보가 DB에 담겨 있기 때문에)
    • JWT: tokon의 Payload에 들어있는 정보만 읽을 수 있다. 따라서 추가적으로 다른 정보가 필요한 경우 DB에 접근해서 가져와야한다.

📍client에서 인증정보 읽기 가능?

session은 client에서 인증정보 읽기 불가능하다. 왜냐하면 sessionrandom string이기 때문이다. 그렇기 때문에 의미있는 데이터는 DB 세션영역에 있기 때문에 조회해야한다.

하지만 JWT의 경우 token 내부에 인증에 필요한 데이터가 base64로 인코딩되어서 존재한다. 따라서 헤더에 있는 데이터를 디코딩해서 가져오면된다.

📍Horizontal Scaling

session의 경우는 사용자의 정보가 DB에 있으므로 수평적확장을 할때 모든 접근시 똑같은 session을 바라보도록 만들어야하기 때문에 resource가 많이 들어 수평적 확장이 어렵다.

하지만 상대적으로 jwt의 경우, 사용자의 정보가 토큰에 담겨있기 때문에 session에 비해 상대적으로 수평적확장이 쉽다.

profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글