All Night Coding

[엘리스 SW트랙 6기] 7주차 회고록 본문

Bootcamp

[엘리스 SW트랙 6기] 7주차 회고록

Boyoung Yun 2023. 9. 24. 16:06
반응형
들어가기에 앞서

이번주가 벌써 백엔드를 배우는 마지막 주차다..😥

시간이 왜 이렇게 빨리 가는지 모르겠다.

개인적으로 이번주는 교육에 많이 집중하지 못했던 한 주였다.

학교 일도 바빠지고, 요즘에 좀 개인적인 힘든 일도 있고 그래서 온라인 강의를 잘 못들었다..

사실 핑계다. 그래도 어리광 부리는건 이번주까지만 하고, 다음주가 방학이기 때문에 머리를 좀 식혀야겠다.


배운 것

1. RESTful API 복습

2. 가입, 식별, 인증, 인가, 접근 통제

3. Session

4. Json Web Token(JWT)


먼저 저번 시간에 배웠던 RESTful API를 간단하게 복습하는 시간을 가졌다.

그리고 RESTful API의 Maturity(성숙도) 라는 것에 대해서 새로 배우게 되었다.

Maturity level 0은 다음과 같다.

https://www.cafe.com/order-service

간단하게 말해서 한 URI 내에서 모든 요청을 다 처리하는 것이다.

post이든, get이든, put이든, delete이든 order-service 하나로 모든 동작을 처리한다.

즉 CRUD를 분리하지 않고, 전달되는 서로 다른 매개변수를 통해 하나의 endpoint에서 동작하는 것이다.

 

Maturity level 1은 다음과 같다.

Request POST https://www.cafe.com/get-menu
Body: {id: 6}

Response HTTP/1.1 200 OK
Content-Type: application/json
{
  "id": 6,
  "name": "ice cappucino"
}

level 0에 리소스에 대한 고려를 더한 방식이다.

URI를 각 동작에 맞게 분리해서 리소스 별로 별도의 URI를 갖도록 구성한다.

예를 들어 get 동작의 URI는 get-menu, update 동작의 URI는 update-menu 등의 다른 이름들을 가질 수 있다.

하지만 하나의 리소스에 대한 작업을 불필요하게 여러 URI로 작성해야 하는 번거로움이 있다.

또한 모든 요청을 200 OK로 받아오기 때문에, 에러가 발생해도 response에서 확인할 수 없다.

 

Maturity level 2는 다음과 같다.

Request POST https://www.cafe.com/menus

Response HTTP/1.1 201 Created
Content-Type: application/json
{
  result : {
   "id": 6,
    "name": "ice cappucino"
  }
}

level 2에서는 URI에 action을 명시하지 않는다.

대신 Response에서 의미있는 HTTP Status Code가 반환된다.

해당 예시에서는 Post 요청이기 때문에 201 Created가 반환된 것을 확인할 수 있다.

또한 400대 에러와, 500 에러 등 다양한 HTTP status Code로 해당 통신의 상태를 파악할 수 있다.

이 단계부터 HTTP Headers를 제대로 사용하는 단계라고 할 수 있다.

생각보다 많은 회사들이 level 2의 단계라고 한다. 트위터도 level 2라고 한다..!

 

Maturity level 3는 다음과 같다.

Request GET https://www.cafe.com/menus/6

Response HTTP/1.1 200 OK
Content-Type: application/json
{
  result : {
    "id": 6,
    "name": "ice cappucino"
    links: {
      "request_order_url": "https://www.cafe.com/orders",
      "all_menus_url": "https://www.cafe.com/menus",
    }
  }
}

level 2와의 차이점은, level 2에 HATEOS가 추가된 것이다.

HATEOS란? 현재 API 호출 이후에 진행할 수 있는 작업/행위들에 대한 URI를 제공하는 것을 뜻한다. (OS 싫어 아니다..ㅎ)

업계에서는 이 단계까지는 구현할 필요는 없다고 한다. 그래서 이정도로 구현하면 정말 잘 구현한 거라고 한다.


다음으로는 가입, 식별, 인증, 인가, 접근 통제에 대해 다시 리마인드 해보는 시간을 가져보자.

1. 가입

먼저 기본적인 회원가입 절차는,

1) ID, PW를 포함한 추가 데이터를 사용자로부터 입력 받음

2) 사용자로부터 입력 받은 데이터를 회원가입 API를 호출하여 서버로 전달

3) ID, PW +@를 한 번 검증하고 해당 데이터들을 DB에 저장

4) 가입 정보 + 인증 데이터(쿠키, 토큰 등)를 클라이언트에게 전달

 

이렇게 진행되는데, 가입 단계에서 Salting이라는 추가 절차가 필요하다.

Salting이란? 직역하면 "소금을 치다"라는 의미인데, 사용자의 패스워드가 유출되었을 때를 대비한 장치이다.

사용자의 패스워드에 랜덤 스트링 값(소금)을 조합한 값을 해싱 함수를 이용해 해시값을 만드는 것이다.

이렇게 처리하면 사용자의 정보가 유출이 되어도 유출된 ID,PW로 로그인이 불가능하다.

 

이제 다시 회원가입 절차로 돌아와서, 대표적인 유저 가입 방식에는 2가지가 존재한다.

1. ID, PW를 이용한 가입

2. 3rd-party 서비스에서 회원 정보를 가져와서 가입(ex OAuth2.0)

 

여기서 OAuth2.0이란?

서비스에 저장된 사용자의 리소스들을 사용자의 승인하에 다른 제3의 서비스가 접근할 수 있도록 하는 표준이다.

OAuth2.0이 없을 때는 다른 서비스의 ID&PW를 미리 입력받아 크롤링해오는 경우가 많았다고 하는데,

이는 회원의 다른 서비스의 계정을 자체 DB에 저장하는 것이기 때문에 보안상 좋지 않았다고 한다.

그래서 이러한 방식의 표준을 만들기 시작했고, 구글 로그인, 카카오톡 로그인 등이 이에 해당한다.

 

2. 식별

사용자(주체)가 본인이 누구인지를 서비스(시스템)에 밝히는 것이다.

사용자가 서비스 내에서 고유한 본인의 유저네임을 패스워드와 함께 제시한다.

실제 사회에서 주민등록증, 운전면허증 등으로 신원을 밝히는 방식과 동일하게 이메일, 유저네임, 아이디 등으로 진행된다.

 

3. 인증

서비스에 접근하려는 사용자가 서비스에 등록된 사용자인지를 판단하는 과정이다.

식별 단계에서 유저로부터 전달된 ID, PW 등으로 사용자를 확인/검증한다.

이는 회원 등록/가입 이후 서비스를 사용하기 위한 1차 관문으로, 로그인이 되었다는 것은 인증이 완료되었다는 것이다.

인증이 완료가 되면 서버는 인증서들(세션 ID, ID token, access token)등을 발급한다.

 

4. 인가

사용자에게 리소스 접근 권한을 부여하는 것이다. 

기본적인 세 가지 요소는 Role(who), Permission(can access), Resource(what) 이다.

Role은 사용자의 역할이며 e-commerce로 예를 들면 구매자, 판매자, 운영자, 시스템 관리자 등으로 구분된다.

Permission은 누가, 어떤 리소스에 어떤 접근(CRUD 등)을 할 수 있는가를 정의한다.

위에서 언급한 예시로 구매자는 품목을 구매할 수 있다. 판매자는 품목을 구매도 할 수 있고 업로드도 할 수 있다. 등을 뜻한다.

Resource는 리소스 그 자체로, 사용자가 어떤 리소스에 접근할 수 있는가를 정의한다.

 

5. 접근 통제

접근 통제는 말 그대로 사용자에게 리소스에 대한 접근을 통제(허가/거부)하는 것이다.

인가 단계에서 부여된 접근 권한을 토대로 해당 권한을 참조하여 접근을 관리하는 과정이다.


다음으로 인증 관리 방식 중 하나인 Session 방식에 대해 다시 알아보도록 하자.

로그인 발생 시 서버가 외부 DB에 로그인한 회원 정보를 session ID와 함께 저장하고, 

Cookie에 session ID를 담아서 클라이언트로 매 request마다 클라이언트로 전송하는 방식이다.

장점으로는 클라이언트 입장에서는 모든 request에 자동으로 쿠키가 포함되어 전송되기 때문에 크게 신경 쓸 일이 없다.

서버에서 로그인 정보를 저장해서 관리하는 Stateful한 인증 방식이며, Scalability(확장성)가 상대적으로 떨어진다.

 

단점으로는 Session을 저장한 저장소가 시스템 문제로 인해 다운되면 모든 유저들이 강제로 로그아웃된다.

그리고 Storage 문제가 존재하는데, 사람들이 여러 기기로 로그인을 시도하면서 그 때마다 회원정보를 저장해야 하므로 저장소의 용량이 기하급수적으로 증가하게 된다.


두번째로 Web Token 방식이 존재하는데, 해당 방식을 다루기 전에 Json Web Token에 대해 알아보자.

Json Web Token(JWT)이란? 서비스에 본인 인증을 마친 유저에게 발급되는 토큰의 한 유형으로, 유저의 분신같은 존재다.

토큰에는 간단한 유저의 정보와 기본 필드(토큰 발급자, 주체, 수신자, 유효기간, 발급 시간, 해싱 알고리즘 타입)등이 포함되어 있다.

기본 구조는 Header, Payload, Signature 구조로 구성되어 있다.

Header에는 토큰에 담긴 서명 해싱 알고리즘 정보가, Payload에는 실제 융통하는 정보들이 담겨지며 Signature에는 토큰 발급자의 전자 서명(hash 값)이 담겨있다.

토큰은 누구나 디코딩해서 내용을 볼 수 있다. 이는 유효성 체크를 위한 것이지 정보 보호를 위한 것이 아니다.

그러므로 토큰에는 민감 정보를 포함해서는 절대 안된다!

Signature 부분에 포함된 서명 정보를 토대로 누가 서명했는지를 확인하고, 이를 통해 유효성 체크를 진행한다.

JWT는 주로 HTTP Header에 Bearer schema에 담기거나 Cookies 또는 HTTP query parameter에 담겨 사용된다.

 

Web Token 인증 관리 방식은, 로그인 발생 시 서버가 사용자를 식별할 수 있는 토큰을 생성하여 클라이언트에게 발급한다.

클라이언트는 발급받은 토큰을 로컬 저장소(local storage 등)에 저장하여 이후 request 시 HTTP header 등에 토큰을 담아 보낸다.

서버는 토큰에 대해 검증을 진행하고, 통과하면 사용자의 요청을 처리한다.

서버에는 로그인 정보가 저장되지 않기 때문에 Stateless한 방식이고, 서버가 별도의 세션 저장소를 둘 필요가 없다.

또한 회원의 로그인 정보를 클라이언트가 가지고 있기 때문에, 서버에 문제가 생겨도 강제 로그아웃되지 않는다.


이번주도 정말 방대한 내용을 배웠다...😅

어떻게 보면 웹서비스에서 가장 중요한 내용인 회원가입/로그인에 대해서 자세하게 다뤄 보았던 시간이였다.

강의를 성실하게 듣지 못해서 너무 아쉬웠던 한 주였지만, 복습하면서 다시 이해할 수 있었던 것 같아서 좋았다.

이번주에 스터디 발표도 있었어서, 팀원분들과 모의 발표까지 진행하면서 발표를 열심히 준비했다.

그 결과 스터디 발표 15분도 꽉꽉 채웠고 1차 스터디부터 퀄리티있는 프로젝트를 진행했다는 칭찬을 들었다.

처음으로 팀장을 맡아서 뭔가를 본격적으로 진행했는데, 결과가 너무 좋아서 보람찼다.

팀원분들도 잘 따라와주셨고, 열정적이신데다 실력도 좋으셔서 나도 덩달아 더 열심히 하게 됐던 것 같다.

길었던 1차 스터디도 끝나고, 다음주 쉬고 이제부터 프로젝트 주간이다!

쉬는 동안에 복습도 좀 하고, 1차 프로젝트에 대한 각오를 다져야겠다. 이번주도 수고했다 나 자신!😊

반응형
Comments