[SW 사관학교 정글 8기] WEEK00 (JWT, SSD)

유선·2024년 3월 16일
0

sw사관학교 정글

목록 보기
1/21
post-thumbnail

정글은 목요일부터 한주를 시작하기 때문에, 입소날이었던 월요일부터 수요일까지는 0주차, 목요일부터 1주차 시작이다.

0주차에는 "정글 입성"으로 미니 프로젝트를 진행하였다.

▶️ 프로젝트 개요

  • 프로젝트 목표 : 입학시험 때 배운 기술들을 토대로 미니 프로젝트 완성하기
  • 프로젝트 일정 : 3월 11일 ~ 3월 14일
  • 프로젝트 주제 : 자유 주제 아이디어 참고 사이트
  • 필수 조건
    1. 로그인 기능
    2. Jinja2 템플릿 엔진을 이용한 서버사이드 렌더링
  • 더 고민해볼 키워드
    1.Bootstrap을 대체할 CSS 라이브러리 사용하기 (Bulma, Tailwind 등)
    2. JWT와 HTTP Authorization header를 사용하여 구현하기 (Session cookie 대비 등장하게 된 배경은?)

🚴🏽‍♂️ 프로젝트 진행

1. 주제 선정

참고사이트를 둘러보던 중, 심리테스트가 있어 정글 8기만을 위한 심리테스트를 만들어서 공유할 수 있으면 좋겠다는 생각으로 "정글러를 위한 나와 닮은 개발자 찾기" 주제가 선정되었다.

2. 주제 발표 및 피드백

프로젝트의 골격인 '와이어 프레임'을 작성하고 주제 발표를 통해 피드백을 받았다.

  • 피드백
    1. 심리테스트 하다가 중간에 나가면? => 다 삭제되도록 할 예정
    2. 심리테스트 로직은 클라이언트에서? 서버에서? => 서버에서 할 예정
    3. 내용이 많지 않은데, 이해도가 적어보임. 초반에 빨리 해야할듯
  • 참고한 다른 팀 피드백
    1. 회원가입, 비밀번호 입력 필수
    1. 회원가입과 로그인을 구분해서 회원가입 버튼을 작게 만들 것

3. 필수 조건 내용학습

  1. JWT 방식을 이용한 로그인 기능 구현
    티타임 시간에 이범규 대표님께서 챗지피티 활용법에 대해 말씀해주셨다. 이론 공부할 때 뭘 공부해야할지 물어보라고 조언해주셨다. 실제로 활용해봤냐고 발표 시간에 모두에게 여쭤보셨고, 활용해본 사람은 많지 않았다.

Q. jwt를 공부하려고 하는데 어떤 순서로 공부해야할까?

1-1. 기본 개념 이해

  • jwt란?

    JWT(Json Web Token)은 Json 객체에 인증에 필요한 정보들을 담은 후 비밀키로 서명한 토큰으로, 인터넷 표준 인증 방식이다.
    공식적으로 인증(Authentication) & 권한허가(Authorization) 방식으로 사용된다.

  • 구성 요소
    JWT는 Header, Payload, Signature 3개로 구성되어 있다.

1-2. JWT의 구조 이해

✔️ 헤더(Header):
헤더는 JSON 형식으로 되어 있으며, 일반적으로 두 가지 정보를 포함한다.

  • 토큰의 유형(typ): JWT임을 나타냄
  • 사용된 해시 알고리즘(algorithm): 토큰 서명에 사용된 해시 알고리즘을 나타냄 (HMAC SHA256 또는 RSA 등)

헤더는 Base64로 인코딩되어 토큰의 첫 번째 세그먼트로 나타난다.

✔️ 페이로드(Payload):

페이로드는 토큰에 담겨 있는 클레임(claim) 정보를 포함한다.

  • sub : 토큰 제목(subject)
  • aud : 토큰 대상자(audience)
  • iat : 토큰이 발급된 시각 (issued at)
  • exp : 토큰의 만료 시각 (expired)

✔️서명(Signature):

서명은 헤더와 페이로드를 기반으로 생성된다.
서명은 비밀 키를 사용하여 생성되며, 이는 토큰의 무결성을 보장한다.
서명은 토큰의 마지막 세그먼트로 나타나며, 페이로드와 헤더의 정보가 변경되었는지 여부를 검증하는 데 사용된다.

1-3. 암호화 및 서명
<대칭 암호화와 비대칭 암호화의 차이>

  • 대칭 암호화(Symmetric Encryption): 대칭 암호화는 동일한 키를 사용하여 데이터를 암호화하고 복호화하는 방식. 토큰을 생성하고 검증하는 데 동일한 키가 사용된다.
    장점은 암호화 및 복호화 속도가 빠르며 구현이 간단하다.
    단점은 키 관리가 어렵다. 키를 안전하게 관리하지 않을 경우 보안이 손상될 수 있다.

  • 비대칭 암호화(Asymmetric Encryption): 비대칭 암호화는 서로 다른 공개 키와 개인 키를 사용하여 데이터를 암호화하고 복호화하는 방식. 토큰을 생성하는 데 개인 키를 사용하고, 검증하는 데는 해당 토큰의 공개 키가 사용된다.
    장점은 키 관리가 간단하고 안전하다. 개인 키는 안전한 서버에만 저장되고 공개 키는 공유될 수 있다.
    단점은 대칭 암호화에 비해 암호화 및 복호화 속도가 느리고, 구현이 복잡하다.

1-4. JWT 사용 시나리오
로그인 시에 세션과 JWT를 모두 사용할 수 있지만, JWT를 선택해야 할 때?
세션 기반 인증은 서버에 상태를 저장해야하기에 확장성이 떨어진다. 하지만 jwt는 상태를 저장하지 않고 토큰 자체에 정보를 포함하므로 서버의 부담을 줄일 수 있다.
서버의 부담을 줄이고 싶을 때, 여러 서버를 사용할때, 클라이언트와 서버 간의 통신이 자주 발생하는 경우에 jwt를 선택한다.

1-5. 보안 고려 사항

  • JWT 방식의 액세스 토큰과 불투명 토큰 방식의 갱신 토큰을 사용합니다.
  • 액세스 토큰과 갱신 토큰을 Secure, HttpOnly, SameSite 쿠키에 저장하여 중간자 공격, XSS, CSRF 등을 방지합니다.
  • 인증서버에서는 사용자 세션을 관리하고 토큰 갱신시에만 세션에 접근하도록 합니다. 이 때 세션에는 사용자의 디바이스 정보, 소스 IP, Origin 등을 저장하여 비정상적인 접근을 감지할 수 있도록 하고, 세션 만료시 다시 인증하도록 합니다.
  • 액세스 토큰이 만료되면 갱신 토큰과 함께 서버에 요청을 보내 새 액세스 토큰을 얻습니다. 이 요청은 갱신 토큰이 탈취되는 것을 방지하기 위해 HTTPS를 통해 이루어져야 합니다.
  • 새 액세스 토큰을 받으면 클라이언트 측의 Secure, HttpOnly, SameSite 쿠키에 저장된 액세스 토큰을 업데이트합니다.
  • 액세스 토큰이 갱신되면, 같은 갱신 토큰으로는 더 이상 새 액세스 토큰을 얻는 데 사용할 수 없도록 이전 갱신 토큰을 서버 측에서 무효화합니다.
  • 매번 사용하기 전에 서버 측에서 JWT 토큰을 확인하여 변조되지 않았는지 확인합니다.

아직 완벽하게 이해하지 못해 내용을 가져온 링크를 추가한다!
https://iam.furo.one/post/jwt-security

1-6. 실전 예제

  • 프로젝트에 적용
  1. 서버 사이드 렌더링
    2-1. CSR(Client Side Rendering)
    - 서버에서 최초 1번 전체 페이지를 로딩하여 보여주고 이후에는 사용자의 요청이 올때 마다, 서버는 데이터만 전달하고 사용자가 주어진 데이터를 가공하여 렌더링 하는 방식
  • 장점
  1. 최초 1회 요청을 제외 하고 페이지 전환 속도가 빠르다.
  2. 서버의 부하가 적다.
  • 단점
  1. 최초 로딩 속도가 느리다.
  2. 최초 html 텍스트가 비어있어 검색에 문제가 있다.
  3. 쿠키나 사용자 정보를 저장하고 있어 보안에 취약할 수 있다.

2-1. SSR(Server Side Rendering)
- CSR과 달리 서버에서 사용자의 요청에 따른 페이지를 렌더링 하여 사용자에게 반환하는 방식

  • 장점
  1. 최초 로딩 속도가 빠르다.
  2. 최초 로딩 시 html 정보가 포함되어 있어 검색이 가능하다.
  • 단점
  1. 페이지 전환마다 서버에서 렌더링 하여 서버의 부하가 크다.
  2. 페이지 전환마다 새로고침 되어 UX가 다소 떨어진다.(깜빡임)

4. 기능 구현
4-1. 회원가입 및 로그인

  • 회원가입
    회원가입 시 가입 정보와 비밀 번호를 서버에 전달하여 DB에 저장한다.이때 비밀번호는 보안상 문제로 hashlib 방식으로 암호화 하여 저장한다.
  • 로그인
    로그인 시 html input값을 서버에 전달한다.
    전달 받은 input값을 DB에서 검색하여 결과값이 있으면 토큰을 내려주고 없으면 로그인 페이지로 리로드 한다.

4-2. 테스트 진행
- 클라이언트에서 서버로 사용자의 답변을 리스트로 전달 한 후, 각 질문에 따른 개발자에 점수를 더하고 빼는 로직을 구현하여 최종 점수가 가장 높은 개발자를 결과 페이지로 보낸다.

4-3. 결과 페이지 공유
- 카카오 개발자 api를 사용하여 개발하였다. (리소스가 많아서 문제 없었음)

🎉 프로젝트 완료 및 피드백

  1. 프로젝트 완료
  • 서버와 클라이언트 완성 후 AWS EC2에 배포하여 외부에서 사이트 접속하게 구현하였다.
  1. 피드백
  • 회원가입 및 로그인 기능을 이용한 페이지가 없다. 내 결과를 다시보기 페이지가 있었다면 좋았을 것이다.
profile
Sunny Day!

0개의 댓글