인증, 인가 - (1)

devJune·2023년 5월 11일
0
post-thumbnail

인증과 인가가 어떻게 이뤄지고 어떤 방식이 있는지 알지 못했을 때의 일이다.
세션 기반 로그인을 구현하는데 로그인에 분명 성공했다고 했는데, 로그인을 다시 할 수 있었던 적이 있었다. 지금 생각하면 아 세션유지가 안된거구나 라고 생각 할 수 있었는데 그 때 당시에는 굉장히 골머리를 앓았던 기억이 있다.

해결하기 위해서 공부 했던 것을 좀 더 보기 좋게 정리해서 오래 기억하도록 기록하겠다.
공부를 하면서 이해해 도움을 받았던 루피님토니님 의 인증 인가의 강의를 토대로 작성하였습니다.


인증과 인가가 정확이 뭔데?

우리는 어렴풋이 인증과 인가가 뭔지는 알고는 있다.

신원 확인 & 신원이 확인된 사람의 접근 허용

좀 더 개발자 답게 말하자면

인증

보호된 리소스에 접근하는것을 허용하기 이전에 등록된 유저의 신원을 입증(Validating)하는 과정.

인가

요청된 리소스에 접근할 수 있는 권한이 있는 인증된 유저인지 입증하는 과정

위에서 말한거와 같이 인가는 항상 인증 다음에 온다.

웹에서의 인증 / 인가

  • Request Header(요청 헤더)
  • Session , Cookie(세션, 쿠키)
  • Token(토큰)
  • Oauth

인증과 인가를 효과적으로 이해하기 위해서는 사전지식이 필요한데,
서버와 클라이언트 그리고 HTTP 에 대해서 알고 있어야 한다.(특히 Statless 속성)

Request Header 활용

만약 우리가 naver에 로그인을 한다고 가정해보자.
naver DB에 회원가입된 정보가 이미 존재하고, 이상황에서 로그인을 하면 어떻게 하면될까?

요청이 들어온 url을 Base64라는 인코더를 이용해서 인코딩을 한 후에 http request를 전달 (이 부분은 클라이언트. 즉, 브라우저가 한다)

  1. url에서 로그인에 관한 부분을 파싱한 후에 인코더를 통해서 인코딩한 문자열을 브라우저가 가지고 있다

  2. 이를 request header의 Authorization에 넣어서 보내주는 개념.

  3. 이렇게 브라우저가 http를 통해 서버로 날려주면 서버에서는 DB 체킹을하고 일치여부를 판단한다.

Request Hearder만 활용시 문제점

만약 로그인한 사용자가 글을 다쓰고, 수정하고 싶다면? 또 인증 요청이 들어가야한다.

그렇다.

매번 인증을 한다.

이러한 점을 해결하기 위해서 브라우저의 힘들 빌리게된다.(정확하게는 브라우저에있는 스토리지의 힘)

스토리지는

  • 로컬 스토리지
  • 쿠키 스토리지
  • 세션 스토리지

있는데 먼저 쿠키를 설명하겠다.

Cookie 활용하기

쿠키에 간단하게 사용자 아이디, 비밀번호를 집어넣는다. 그리고 사용자가 인증이 필요한 요청을 할때 같이 준다. 그러면 확인을 하고 원하는 자원을 받게된다.
1. Cookie에 사용자의 ID, PW를 넣는고 인증이 필요한 요청을 할 때 Cookie도 같이 Server에 보내준다.
2. Server는 DB에 쿠키에 담은 정보를 확인 요청하게 된다.
3. DB는 Server가 요청한 DB 값이 있는지 확인 후 callback 해준다.
4. Server는 다시 client에 callback 해준다. 그리고 사용자는 원하는 자원을 얻을 수 있다.

(사용자의 아이디와 비밀번호를 그대로 노출하기 때문에 보안에 매우 취약하다.)

이러한 단점을 해결하기 위해서 Session을 활용하여 Server에 도움을 요청하게 된다.

Session 활용하기

방식은 동일하다.

  1. Cookie에 사용자의 ID, PW를 넣는고 인증이 필요한 요청을 할 때 Cookie도 같이 Server에 보내준다.
  2. Server는 DB에 쿠키에 담은 정보를 확인 요청하게 된다.
  3. DB는 Server가 요청한 DB 값이 있는지 확인 후 callback 해준다.
  4. Session은 인증된 사용자의 식별자와, 랜덤 한 문자열로 SESSIONID를를 만들어서
  5. 응답(Response Header)로 넘겨주고
  6. Client가 저장할 수 있도록 하는 것이다.
    그림과 같이 세션은 서버에서 관리를 한다. 그래서 탈취된 세션을 삭제를 하게된다면,세션 자체를 이용하지 못하게 되 보안상 이점이 있다.

장점

  1. Client의 보안이 낮은 데이터를 갖고 있게 되지 않게 된다. 그렇게 되면 해커가 정보를 가져가게 되더라도 크게 위험하지 않게 된다.
  2. SESSION이 만료기간을 설정할 수 있어 해커가 가져가게 되더라도 기한이 만료되면 유효하지 않게 되는 장점이 있다.
  3. Session의 관리를 Server 자체에서 하고 있어 탈취된 Session을 Server에서 삭제하게 되면 더 이상 Session을 사용하지 못하게 된다.

그렇다면 단점이 존재 안하나? 그건 아니다.

단점

빨간 점선은 Load Balancer 이다.

  1. 서비스가 잘 돼서 서버를 여러 개 두게 되면 로드 밸런서도 생기게 된다.

    Load Balancer 란? : 서버에 가해지는 트래픽을 여러 대의 서버에서 균등하게 분산시켜주는 역할.

  2. 한 번 인증돼서 SESSIONID를 받게 되면 다음 요청 땐 Session으로만 이용해서 요청하게 된다.

  3. 즉, 이젠 DB까지 확인하지 않고 Server에서 Session을 확인하여 처리할 수 있게 됐다는 뜻이다.

다른 서버에 인증 요청을 보내면 어떻게 될까?

  1. 1번째 인증을 완료하고 2번째 인증이 필요해 다시 요청을 보낸다.
  2. SESSIONID 값이 저장되어 있는 3번째 서버가 아닌 2번째 서버에 요청을 보내게 된다.
  3. 이 문제의 원인은 Server 하나하나 자체에서 Session을 관리하고 있기 때문에 문제가 발생하게 된다.

문제 해결 - Session DB

Session Storage( 세션 DB) 통해서 SessionID 요청을 한 DB에 요청하여 해결할 수 있다.

그러나 또 다른 문제가 발생한다.

  • Client가 많아져서 요청이 많아지게 되면 Session Storage에 과부하가 생겨 DB가 터지게 된다.
  • 사용자를 위해 Cookie나 Browser의 힘을 빌려서 계속 로그인까지 하게 해줬는데 이젠 보안상의 문제가 생겨 Server 쪽에 와서 인증/인가를 해줬더니 문제가 계속 발생하게 된다.

Stateful/Stateless

  • 우리는 클라이언트, 서버 ,Session저장소 모두 사용자의 상태관리를 할 수 있게 해봤다.그랬더니 문제가 발생하였다.

  • 그 이유는 Client와 Server가 서로 통신할 때 사용하는 http와 Server 자체가 지향하는 REST API가 무상태성(Stateless)을 기초로 하기 때문이다.

  • 그런데 실제로 인증과 인가를 진행할때 사용자의 정보 , 상태를 3군데 모두 가지고 있었다. 그 말은 상태성을 가지고 있었다는 것이다.

  • 패러다임이 충돌을 하기 때문에 문제가 생긴것이다. 이것을 해소해야지 문제가 해결된다.


처음으로 돌아와서...

우리는 위에서 사용자의 상태를 클라이언트와 서버 둘다 모두에게 맡겨봤었다.
이제 요청과 응답안에 담아 보기로 했다.

그래서 나오게 된것이

Token

이다.

JWT(Jason Web Token)

  • JWT 자체는 해독하기 쉽기 때문에 JWT 내에는 민간한 정보를 담지 않는다.
  • Secret Key가 중요한 만큼 노출되면 JWT 자체도 끝이 나게된다.
  • Token을 사용하기 위해서는 Secret key를 서버 내부에서 관리를 해야 한다.

JWT 활용하기

JWT 로직

  1. Request를 보낸다.
  2. Server 에서 DB로 ID,PW를 확인한다.
  3. 확인이 완료되면
  4. Secret Key를 이용해 Token을 만들어낸다.
  5. 만든 토큰을 Header에 담아서 Clinet에 보낸다.
  6. 이 후 부터 사용자는 해당 JWT로 요청과 응답을 받는 형태가 된다.

JWT의 장점

  1. 세션 스토리지 같은 경우 세션 DB와 연관성이 있었는데,로드 밸런서가 요청하는 곳에 각자 서버가 가진 Secret key로 해독해서 인증을 진행하면 되고, 요청을 반환하면 된다는 장점이 있다.
  2. 확장성이 좋아 서버가 많아져도 같은 방식으로 진행할 수 있다.

그렇다면 단점은 없는가?

JWT(Token 기반)의 단점

Access Token이 탈취 당한다면 해커는 사용자와 똑같은 지위를 갖게 된다.

Token 만료기한

Token 만료기한을 설정해 놓으면 만료기간 이후 해커뿐만 아니라 사용자도 사용할수 없어서 불편할 수 있다.

그래서 나온 개념이 ?

Refresh Token

  1. 요청을 보낸다.
  2. Secret Key를 통해 Token을 만들어낸다.
    이때 Access Token과 Refresh Token을 만들어낸다.
  3. Access Token은 저장하지 않고, Refresh Token만 따로 저장소에 저장하게 된다.
  4. Access Token과 Refresh Token을 한 번에 응답 헤더(Response Header)로 보내게 된다.
  5. Client는 둘 다 저장하게 된다.
  6. 2번에서 만든 Access Token은 Server에 저장하지 않는다.
  7. 다음부터는 Client가 Access Token을 이용하여 요청을 보내게 된다.

Access Token 만료

  1. 사용자는 똑같이 요청을 보내게 된다.
  2. 만료된 access token 이면 만료되었다고 Client에 알려준다.
  3. 그럼 Client는 다시 Access Token과 Refresh Token을 한 번에 Server에 요청하게 되어 저장소에 있는 Refresh Token을 비교하고 확인되면
  4. Secret key를 이용하여 갱신된 Access Token을 다시 발급해 주고 준다.
  5. 사용자는 갱신된 Access Token을 사용하여 다음 요청들을 보내게 된다.
  6. 만약, Refresh Token이 만료되었다면, Secret key를 통해 Access Token과 Refresh Token을 다시 발급하여 위와 같은 로직을 수행하게 된다.

Token의 핵심

Token 장점

  1. 토큰으로 상태 관리를 하기에 따로 세션을 둘 필요가 없다.
  2. 효율성이 좋아짐, DB에 요청하여 직접 확인하지 않아도 되기 때문에 속도가 빠르다.

Token 단점

토큰 관리를 해야 하며, 결국 토큰도 탈취당할 수 있다. 따라서 보안에 꾸준히 신경을 써야한다.

OAUTH 기반 인증 인가

는 다음 포스팅에서 이어서 하도록 하겠다.

profile
지식 저장소

0개의 댓글