[Security] 인증과 인가
![[Security] 인증과 인가](/assets/img/development/server/2023-01-18/authentication_authorization_cover.png)
“해당 포스팅은 우아한Tech의 [10분 테코톡] 🎡토니의 인증과 인가의 영상을 기반으로 포스팅하였습니다. 또한 설명이 너무 잘되어었어 복습하고자 글로 남깁니다. 영상을 제작해주신 우아한Tech와 토니님에게 감사드립니다.”
#목차
실 생활에서의 인증과 인가
인증(Authentication)이란?

- (지문 또는 얼굴 등) 입증 가능한 정보로 인증이 필요한 곳에 입증하는 과정이다. 즉, 식별 가능한 정보로 서비스에 등록된 유저의 신원을 입증하는 과정
- 쉽게 말해, 아이폰으로 계좌이체를 하려고 할 때, 어플에 접근하여 로그인 하는 과정이 인증이다.
인가(Authorization)란?

- 입증(인증) 된 신원의 권한에 대한 허가를 나타내는 것이 인가이다. 즉, 인증된 사용자에 대한 자원 접근 권환 확인이다.
- 쉽게 말해, 은행 어플에 접근하여 로그인(인증) 한 후, 계좌이체에서 마지막 송금 과정시 OTP, 생체인증 등 권한을 통한 작업이 인가이다.
Web에서의 인증과 인가

“Web에서 사용자가 게시판에 글 작성하는 서비스라고 생각해보자.”
- 사용자가 사이트에 회원가입과 로그인을 하는 과정이 인증이다.
- 인증이 됐으면 게시판에 게시글을 쓸 수 있는 권한이 생겼다. 이 과정이 인가이다. 다른 사람이 게시판에 작성한 게시글 또한 읽을 수 있다.
- 하지만, 다른 사람이 작성한 게시글을 수정할 수 없다. 왜냐하면, 다른 사람이 작성한 게시글을 수정 할 권한(인가)이 없기 때문이다. 인가가 적용된 개념이다.
1.Request Header 활용

“Client와 Server 사이에 HTTP로 통신하게 된다. 가상의 사이트에 회원가입이 되어있는 상태라고 가정해보자.”
- DB에 ID, PW 정보가 있다. 사용자가 login URL로 접근하게 되면 login 요청을 보낼 수 있게 된다.
- 만약, 로그인 API가 구축되어 있는 상태라고 가정 했을 때, URL 앞에 ID, PW를 넣어주고 요청하게 되면 login이 된다.
- 2번의 처리 과정을 간단하게 알아보자.

“브라우저 요청 처리 방법은 요청 URL을 Base64로 encoder를 이용하여 encoding 하게 된다.”
- URL의
user:1q2w3e!부분을parsing하여 Base64를 통해encoding을 하고- 그렇게 변환된
문자열을 같게되고 - 요청 헤더의
Authorization에 넣어서 보내주는 개념이다.

“여기까지가 기본적으로 로그인한 상태의 로직이다.”
- Client가 encoding 한 요청 헤더를 Server에 요청하게 된다.
- Server가 DB checking을 하고
- DB에 값이 있으면 Client에
OK사인을 주게 된다.
Request Header만 활용할 시 문제점
- 어떤 처리를 할 때(ex) 등록, 수정, 삭제 등…) 매번 인증을 해야 하는 번거로움이 발생하게 된다.
- 이걸 해결하기 위해 Browser의 Storage를 활용하게 된다.
Browser 활용하기
- Browser의 Storage 종류
- Local Storage
- Cookie Storage
- Session Storage
Cookie Storage

“Cookie Storage의 로직”
- Cookie에 사용자의 ID, PW를 넣는고 인증이 필요한 요청을 할 때 Cookie도 같이 Server에 보내준다.
- Server는 DB에 쿠키에 담은 정보를 확인 요청하게 된다.
- DB는 Server가 요청한 DB 값이 있는지 확인 후 callback 해준다.
- Server는 다시 client에 callback 해준다. 그리고 사용자는 원하는 자원을 얻을 수 있다.
- 사용자 입장에서는 굉장히 편리한 방법이다.

하지만, 해커의 입장에서도 굉장히 편리한 방법이다.- 보안에 취약하게 노출되어 있어 사용자 정보를 쉽게 탈취할 수 있게 된다.
- Client가 Server보다
상대적으로보안이 취약하다는 단점이 있다.
- 이러한 두 가지 단점을 해결하기 위해(보안 향상) Session을 활용하여 Server에 도움을 요청하게 된다.
Session Storage

“Session Storage의 로직.
1번부터3번의 로직은Cookie Storage와 같다.”
- Cookie에 사용자의 ID, PW를 넣는고 인증이 필요한 요청을 할 때 Cookie도 같이 Server에 보내준다.
- Server는 DB에 쿠키에 담은 정보를 확인 요청하게 된다.
- DB는 Server가 요청한 DB 값이 있는지 확인 후 callback 해준다.
- Session은 인증된 사용자의 식별자와, 랜덤 한 문자열로
SESSIONID를를 만들어서 - 응답(Response Header)로 넘겨주고
- Client가 저장할 수 있도록 하는 것이다.
장점
- Client의 보안이 낮은 데이터를 갖고 있게 되지 않게 된다. 그렇게 되면 해커가 정보를 가져가게 되더라도 크게 위험하지 않게 된다.
- SESSION이
만료기간을 설정할 수 있어 해커가 가져가게 되더라도 기한이 만료되면 유효하지 않게 되는 장점이 있다. - Session의 관리를 Server 자체에서 하고 있어 탈취된 Session을 Server에서 삭제하게 되면 더 이상 Session을 사용하지 못하게 된다.
단점

“중간에
Load Balancer가 여러 대의 서버에 요청하게 된다.”
- 서비스가 잘 돼서 서버를 여러 개 두게 되면 로드 밸런서도 생기게 된다.
Load Balancer란? : 서버에 가해지는 트래픽을 여러 대의 서버에서 균등하게 분산시켜주는 역할.
- 한 번 인증돼서
SESSIONID를 받게 되면 다음 요청 땐Session으로만 이용해서 요청하게 된다. - 그 말은 이젠 DB까지 확인하지 않고 Server에서 Session을 확인하여 처리할 수 있게 됐다는 뜻이다.

“이 상황에서 user가 두 번째 인증 요청을 보내게 된다.”
- 1번째 인증을 완료하고 2번째 인증이 필요해 다시 요청을 보내게 된다.
- 그런데, 로드 밸런서가 SESSIONID 값이 저장되어 있는 3번째 서버가 아닌 2번째 서버에 요청을 보내게 된다.
- 2번째 서버에는 SESSIONID 값이 없어 오류가 발생하게 된다.
- 이 문제의 원인은 Server 하나하나 자체에서 Session을 관리하고 있기 때문에
문제가 발생하게 된다.
문제 해결 - 세션 DB

“Session Storage(세션 DB)를 통해 SESSIONID 요청을 한 DB(Session Storage)에 요청하여 해결. 그런데…”
또 다른 문제 발생 - 세션 DB의 문제

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

Client,Server,Session 저장소3가지 모두 사용자의 상태를 관리할 수 있게 하였다. 그랬더니 문제가 발생하였다.- 그 이유는
Client와Server가 서로 통신할 때 사용하는http와 Server 자체가 지향하는REST API가무상태성(Stateless)을 기초로 하기 때문이다. - 그런데, 실제로 인증과 인가를 구현할 때에는 사용자의 정보, 상태를
Client,Server,Session 저장소3군데 모두 가지고 있었다. - 그 말은 상태성을 갖고 있다는 이야기다.
- 두 패러다임이
충돌되고 있다. 두 패러다임의 충돌을 해소해 보자. Client,Server,Session 저장소모두 상태를 맡겨보았으니 나머지통신(정보의 흐름)에 맡겨보자.- 요청과 응답 안에 사용자의 상태를 담아보자. 그걸로만 사용자의 인증과 인가를 처리하자.
- 그것이 바로
TOKEN을 활용한 인증과 인가이다.
JWT

“
Secret key를 사용해서 JWT를 만들어 내고 인증 과정을 거친다.”
- JWT 자체는 해독하기 무척 쉽기 때문에 JWT 내에는
민감한 정보(PW)를 대부분 담지 않는다. - 그리고
Secret key중요한 만큼 노출되면 JWT 자체도 끝이 난다. - 그래서 토큰을 사용하기 위해서는
Secret key서버 내부에 잘 관리해야 한다.
JWT 활용하기

“
JWT로직”
- 요청을 보낸다.
- Server에서 DB로 ID, PW를 체크한다.
- 체크가 완료되면
Secret key를 이용해서 토큰을 만들어 낸다.- 실제로는 더 길 수 도 있다.
Secret key를 이용 만든 토큰을header에 담아서 Client에 보내준다.- 다음부터 사용자는 해당
JWT로 요청과 응답을 받는 형태가 된다.
JWT 좀 더 알아보기

“
token”
- Client로부터 서버로 요청이 왔다.
유효성 검사를 서버에 있는Secret key로 진행하게 된다.- 거기서 유효하지 않게 되면 버리게 되고, 유효하게 되면 다음 단계인
사용자 정보를 파악하게 된다. - decoding 하기 쉽기 때문에 사용자 정보 중에 이름으로 어떤 사용자인지 찾아낸다.
만료 시기로 토큰의 만료 시기를 활용할 수 있다.권한으로 사용자의 권한(사용자/어드민 등)을 확인할 수 있다.- 주의,
비밀번호는 담으면 안 된다. 비밀번호를 담게 되면 디코딩을 쉽게 할 수 있다는 점 때문에 노출되기 쉽기 때문이다. Secret key를 통해서 유효성 검사를 통과한 토근은 이미인증을 받은 토큰이다.
JWT 장점

“
jwt의 장점”
- Session Storage같은 경우 Session DB와 연관성이 있었는데, 이제는 로드 밸런서가 요청하는 곳에 각자 서버가 가진
Secret key로 해독해서 인증을 진행하면 된고 요청을 반환하면 된다는 장점이 있다. 확장성이 좋아 서버가 많아져도 똑같이 진행할 수 있다.
Token 단점

해킹을 당할 수 있다.- Access Token이 탈취 당하면 해당 해커는 사용자와 똑같은
지위를 갖게 된다.
Token 만료기한
- Token 만료기한을 설정해 놓으면 만료기간 이후 해커뿐만 아니라 사용자도 사용할 수 없게 된다.
- 그래서 사용자 입장에선 굉장히 불편할 수 있다.
Refresh Token

“
Refresh Token은 위 문제를 해결하고자 나온 Token 방식이다.”
- 요청을 보낸다.
Secret key를 통해 Token을 만들어 낸다. 이때Access Token과Refresh Token을 한 번에 만들어 낸다.- 그리고
Access Token은 저장하지 않고,Refresh Token만 따로저장소에 저장하게 된다. Access Token과Refresh Token을 한 번에응답 헤더(Response Header)로 보내게 된다.- Client는 둘 다 저장하게 된다.
- 2번에서 만든
Access Token은 Server에 저장하지 않는다. - 다음부터는 Client가
Access Token을 이용하여요청을 보내게 된다.
Access Token 만료

“
Access Token이 만료되면…
사용자는Access Token이 만료되었다는 사실을 모르고,알 필요도 없다.”
- 사용자는 똑같이 요청을 보내게 된다.
- 만료된 access token 이면 만료되었다고 Client에 알려준다.
- 그럼 Client는 다시
Access Token과Refresh Token을 한 번에 Server에 요청하게 되어 저장소에 있는Refresh Token을 비교하고 확인되면 Secret key를 이용하여갱신된Access Token을 다시 발급해 주고 준다.- 사용자는 갱신된
Access Token을 사용하여 다음 요청들을 보내게 된다. - 만약,
Refresh Token이 만료(7일 이전( 예) 2023.01.25 ~ 만료기한 2023.02.01)) 되었다면,Secret key를 통해Access Token과Refresh Token을 다시 발급하여 위와 같은 로직을 수행하게 된다.
Token 핵심
Token 장점
- 토큰으로 상태 관리를 하기에 따로 세션을 둘 필요가 없다.
효율성이 좋아지고, DB에 요청하여 직접 확인하지 않아도 되기 때문에 속도가 빠르다.
Token 단점
- 토큰 관리를 해야 하며, 결국 토큰도
탈취당할 수 있다. - 보안에 있어
꾸준히 신경써야 한다.
마치며 - 더 공부해야 할 것들
보안(Security)
- Token
- JWT
- OAuth
- OAuth1.0
- OAuth2.0
- 인증 방법
- 인증 서버
- Option
- HttpOnly : 서버에서 클라이언트로 정보를 보낼때 보낸 정보에 달아주는 옵션. Storage에 저장된 정보에 함부로 접근할 수 없게 만드는 옵션.
- Sliding Session : Refresh Token과 상호 보안적인 것.
- Refresh Token : Sliding Session과 상호 보안적인 것.
- SSL/TLS1.3 : 접근하기 쉽고 가성비 좋은 보안 방법. => HTTPS(가장 추천하는 방식)
- Haking 방법
Continue with [Security] OAuth