[Security] 인증과 인가
“해당 포스팅은 우아한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