인증과 인가

푸드테크·2022년 8월 15일
0
post-custom-banner

안녕하세요 푸드테크팀 백엔드 개발자 박형민 입니다

오늘은 인증과 인가에 대한 내용에 대해 포스팅 해보고자 합니다.

인증이란

  • 식별 가능한 정보로 서비스에 등록된 유저의 신원을 입증하는 과정입니다.

ex)
1. 내가 푸드 건물에 입장할 수 있도록 건물앞에서 인증한다.
2. 사용자가 서비스를 사용할 수 있도록 인증한다.



인가란

  • 인가란, 권한에 대한 허가입니다.
  • 즉, 인증된 사용자에 대한 자원 접근 권한 확인을 말합니다.

ex)
1. 내가 푸드 건물에 들어가서 화장실도 가고, 업무도 볼순 있지만, 보안실에는 들어가지 못한다.
2. 사용자가 구매한 상품에 대해 리뷰를 작성할 순 있지만, 다른 사용자의 리뷰를 지울 수 있는 권한은 없다.

👉 이렇게 사용자의 권한을 나타내는 것을, 사용자에 대한 인가라 합니다.


즉, 선행되어야한 것은 인증 ➡️ 인가 의 순으로 진행되어야 합니다.


인증하기

인증은, 로그인이라고 말할 수 도 있습니다.
이제 로그인을 해봅니다!

Request Header

  • 가장 단순한 방식입니다. Reqest Header 에 사용자 정보를 넣어서 API 요청시 정보를 같이 보내는 것입니다.

Basic 인증방식이라도 하며, 사용자의 정보를 Base64로 인코딩 된 문자열을 AuthoriZations에 넣어서 보내주는 개념입니다.

  1. 이렇게 Http 에 정보를 담아 서버에 요청을 보내고
  2. DB의 사용자 정보를 체크해, 인증해 줍니다.

🙌 Request Header 만 활용했을 때의 단점

  1. 매 요청마다 사용자가 인증해야한다.
  2. 정보를 탈취당하거나, 패킷 도청을 당할 위험이 매우매우 높다.

이러한 단점을 해결하기 위해 Browser 의 Storage 의 힘을 빌려서 해결할 수 있습니다.



인증 유지하기

Browser

Browser 의 Storage 에는, Local Storage, 쿠키, 세션 등이 존재합니다.

사용자의 매 요청마다, 인증정보를 입력하지 않도록 하기위해,

이러한 Browser 의 Storage 에 사용자 정보를 저장해두었다가, 인증정보가 필요할 때마다
저장된 정보를 꺼내서 보내는 방식입니다.

장점

  • 사용자의 입장에서 굉장히 편리합니다.
  • 한번 정보를 저장하고 나면, 더이상 클라이언트의 입장에서는 인증에 대해서 신경쓰지 않아도 됩니다.

단점

  • 해커의 입장에서도 굉장히 편리합니다.
  • 클라이언트는 상대적으로 서버보다 보안에 취약할 수 밖에 없습니다.
  • Storage에 저장한다는 것은, 정말 단순하게 행으로된 정보를 저장한다는 것이기 떄문에 매우 보안에 취약합니다.



안전하게 인증하기

Server

  • 이러한 보안적 이슈를 해결하기 위해, Server 를 이용할 수 있습니다.

Session

세션이란, 사용자가 정보를 인증하면, 사용자의 정보를 클라리언트가 그대로 가져가는게 아닌,

임의의 문자열로 서버에서 세션 ID를 만들어 사용자에게 세션 ID를 저장하고 있도록 하는 방법입니다.


장점

  1. 클라이언트가 날것의 정보를 raw한 데이터로 저장하지 않기 때문에, 정보를 탈취당해도 위험이 적습니다.
  2. 세션의 만료기간을 저장할 수 있기 때문에, 이것또한 보안상의 이점을 가져갈 수 있습니다.

단점

  1. 서버에서 세션 ID를 관리해주어야하기 때문에 데이터의 관리를 해주어야합니다. (그리 큰 단점이라고는 생각되지 않긴합니다..ㅎ)
  2. 서버가 한대가 아닌 여러대로 나누어져있는 상황이라면 (ex - 로드밸런싱) 1번 서버에서 세션 ID를 발급받았는데, 다음 요청에서는 2번 or 3번 서버로 요청을 보낸다면, 세션 정보는 1번 서버에만 세션 아이디 값이 있기 때문에 에러가 납니다.
  3. 이러한 문제점을 해결하기 위해, 세션 스토리지를 사용합니다.
    • 모든 서버의 세션을 한 곳에서 두어서 해결하기 위한 것입니다.
    • 요청이 너무 많아지면, 서버가 많아질 수 록 많은 요청을 보내기 때문에 서버거 터질수도 있습니다.



효율적으로 인증하기

클라이언트, 서버, 세션에 한번씩 사용자의 정보를 맡겨보니 문제가 계속 생겼습니다.
따라서 이번에는 정보의 흐름에 맡겨보자..! 해서 나온게 바로 Token 입니다.

Token

정보의 요청과 응답안에 Token을 이용해서 사용자의 상태를 담고, 그것을 이용해서 인증과 인가를 처리하는 것이 Token을 이용한 인증과 인가 방법입니다.

JWT

  • Jwt 란, Json Web Token의 약자 입니다.

JWT는 시크릿 키를 활용하여 JWT를 발급받고, 시크릿 키를 사용해서 JWT 의 인증 과정을 거칩니다.

  1. 사용자 정보를 바탕으로 인증이 되면, 시크릿 키를 활용해서 JWT 를 사용자에게 보냅니다.
  2. 사용자는 다음 요청에 이 JWT 를 보내고 서버에서 시크릿키만을 이용해서 JWT의 토큰의 유효성을 체크합니다.
  3. 유효한 토큰이라면 사용자 인증을 거칩니다.
  4. 그 다음, 토큰의 만료기간을 체크하고
  5. 권한을 체크합니다.

장점

세션과 달리, 서버가 가진 시크릿 키를 이용하기 때문에, 서버의 부하와 서버가 여러대가 늘어나도 각각 똑같은 방법으로 인증과 인가가 진행되기 때문에 서버 확장성에 대한 이점을 가져갈 수 있습니다.

단점

  • 똑같이, 해커가 Jwt 를 탈취하면 모든 걸 할 수 있습니다.
  • 이러한 문제점을 해결하기 위해 JWT 토큰의 만료기간을 보통 짧게 가져갑니다.
  • 토큰의 만료기간을 짧게 가져가는 대신 Refresh Token 을 이용하는 방법이 있습니다.

Refresh Token

  • 토큰이 만료되었다면, 사용자의 인증이 끝다는 말입니다.
  • 즉 로그아웃이 되었기 때문에, 사용자는 다시 로그인을 해야합니다.
  • 이러한 과정이 너무 짧은 주기로 이루어진다면 사요자의 사용성이 저하되기 때문에 Refresh Token 이라는 개념이 나왔습니다.

Refresh 과정

  1. 사용자는 액세스 토큰이 만료되었을 때 요청을 보내서 만료 됬다는 응답을 받으면
  2. 클라이언트에서 다시, 액세스 토큰과 리프레쉬 토큰을 서버에 보냅니다.
  3. 서버에서는 리프레쉬 토큰이 유효하다면, 클라이언트에게 다시 새로운 액세스 토큰을 발급해줍니다.

토큰 정책

사실 Refresh Token 에 대해서는 Jwt 액세스 토큰의 보안을 위해 나온 개념이기 때문에 딱, 이게 정답이다! 라는 정보가 없습니다.

  1. 액세스 토큰을 발급할 때, Refresh 도 새로 발급해서, 계속계속 보안성을 가져가면서 무한 로그인을 유지한다던가
  2. Refresh 의 기간이 끝나면 새로 로그인을 하도록 한다던가
  3. Refresh를 아예 사용하지 않는다거나 (애플의 정책)
  4. Refresh를 사용하지 않으면서 액세스 토큰을 short-term, long-term 2가지로 분리한다거나 (페이스북)
  5. 서비스에서 관리하는 고유한 키값으로 토큰을 재발급 받는다거나 (Google)




등등,, 토큰 정책은 각 서비스의 상황에 맞춰 최대한 머리를 싸매고 결정해야할 주요한 정책이라고 생각합니다!!

profile
푸드 테크 기술 블로그
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 8월 21일

좋은 글 잘 봤습니다. 추가적으로 토큰 로그인 방식의 문제점은 로그아웃을 구현하기 위해서는 추가적인 구현이 필요하다는 내용도 정리 되었으면 더 좋았을거 같습니다.

답글 달기