S E P H ' S
Session 관리, 대안 본문
우리가 사용하는 웹사이트를 생각해보면 로그인을 한 번 하고나면 그 사이트에서는 다시 로그인 할 필요 없이 여러 페이지의 기능들을 사용할 수 있고 나중에 다시 접속했을 때도 그 로그인 상태를 유지할 수도 있다.
하지만 이를 가능케 하려면 HTTP의 비연결성(Connectionless) 과 비상태성(Stateless)을 보완하여 서버가 클라이언트를 식별, 인증하도록 해주는 것이 필요한데 그것이 쿠키(Cookie)와 세션(Session)이다.
세션(Session)은 비밀번호와 같은 인증 정보를 쿠키에 저장하지 않고 대신에 사용자의 식별자인 JSESSIONID를 저장한다. 서버에는 인증 정보와 더불어 이 ID에 해당하는 로그인 상태, 마지막 로그인. 시간, 닉네임, 만료기한 등의 정보를 저장한다. 보안상 서버는 사용자의 컴퓨터보다는 훨씬 안전하기 때문에 인증에는 세션을 사용한다.
기존의 프로젝트에서 세션의 동작 순서는 다음과 같다.
1. 클라이언트가 서버에 Request를 보낸다.
2. 서버에서는 session id 쿠키 값이 없는 것을 확인하고 새로 발급하여 응답한다.
3. 클라이언트는 전달받은 session id 값을 매 요청마다 헤더 쿠키에 넣어서 요청하고,
4. 서버는 session id를 확인하여 사용자를 식별한다.
5. 클라이언트가 로그인을 요청하면 서버는 session을 로그인한 사용자 정보로 갱신하고 새로운 session id를 발급하여 응답한다.
6. 이후 클라이언트가 로그인을 요청하면 session id 쿠키를 요청과 함께 전달하고 서버에서도 로그인된 사용자로 식별 가능하다.
7. 클라이언트 종료 ( 브라우저 종료 ) 시 session id 제거, 서버에서도 세션 제거한다.
이러한 세션 / 쿠키를 사용한 인증 방식은 악의적인 사용자가 HTTP 요청을 가로채 그 안에 들어있는 쿠키를 훔칠 수 있다는 단점이 존재한다. 해결책으로는 HTTPS를 사용해 요청 자체를 탈취해도 안의 정보를 읽기 힘들게 하거나, 세션에 유효시간을 넣어주는 방법이 있다. 또한 세션 / 쿠키와 함께 대표적인 인증방식인 토큰 기반 인증 방식 (JWT : Json Web Token) 방식이 해결책으로 존재한다.
JWT ( Json Web Token )
JWT 는 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다. 토큰을 만들기 위해서는 크게 3가지, Header, Payload, Verify Signature가 필요하다.
Header | 3가지 정보를 암호활 방식(alg), 타입(type) 등이 들어감. |
Payload | 서버에 보낼 데이터가 들어감. 일반적으로 유저의 고유 ID값, 유효기간이 들어감. |
Verify Signature | Base 64 방식으로 인코딩한 Header, payload 그리고 SECRET KEY를 더한 후 서명됨. |
Header, Payload는 인코딩될 뿐 따로 암호화 되지 않는다. 따라서 JWT 토큰에서 이 두 요소는 누구나 디코딩하여 확인할 수 있다. 하지만 Verify Signature는 SECRET KEY 를 알지 못하면 복호화 할 수 없다.
JWT가 인증에 사용되는 방식은 다음과 같다.
1. 사용자가 로그인을 한다.
2. 서버에서는 계정정보를 읽어 사용자를 확인한 후, 사용자의 고유한 ID값을 부여하고 기타 정보와 함께 Payload에 넣는다.
3. JWT 토큰의 유효기간을 설정한다.
4. 암호화할 SECRET KEY를 이용해 ACCESS TOKEN을 발급한다.
5. 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보낸다.
6. 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효기간을 확인한다.
7. 검증이 완료 되면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져온다.
JWT는 발급후 검증만 하면 되기 때문에 별도의 저장소 관리가 필요한 세션/쿠키보다 간편하다. 또한 확장성이 뛰어나다. 하지만 이러한 JWT에도 단점이 있는데, 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능하기 때문에 악의적인 사용자는 유효기간 내에 지속적으로 정보에 접근이 가능하다. 이에 대한 해결책으로 (Access Token + Refesh Token) 방식이 존재한다.
Access Token + Refresh Token
Refresh Token은 Access Token 과 똑같은 형태의 JWT이다. 처음 로그인을 완료하면 Access Token 과 동시에 발급되는 Refresh Token은 보다 긴 유효기간을 갖고, Access Token이 만료됐을 때, 새로 발급해주는 열쇠가 된다. Access Token이 탈취당하면 정보가 유출되는 것은 동일 하나, 짧은 유효기간 안에만 사용 가능하기에 안전하고, Refresh Token의 기간이 만료됐다면 사용자는 새로 로그인해야 한다.
Access Token + Refresh Token의 사용 방식
1. 사용자가 ID, PW를 통해 로그인한다.
2. 서버에서는 회원 DB에서 값을 비교한다.
3. 로그인이 완료되면 Access Token, Refresh Token을 발급한다. 이때 일반적으로 회원DB에 Refresh Token을 저장한다.
4. 사용자는 Refresh Token은 안전한 저장소에 저장 하고, Access Token을 헤더에 실어 요청을 보낸다.
5. Access Token을 검증하여 이에 맞는 데이터를 보낸다.
6. 시간이 지나 Access Token이 만료되면 이전과 동일하게 Access Token을 헤더이 실어 요청을 보낸다.
7. 서버는 Access Token이 만료됨을 확인하고 권한없음을 신호로 보낸다.
8. 사용자는 Refresh Token과 함께 Access Token을 함께 서버로 보낸다.
9. 서버는 받은 Access Token이 조작되지 않았는지 확인하고 Refresh Token과 사용자의 DB에 저장되어. 있던 Refresh Token을 비교한다. Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 발급해준다.
10. 서버는 새로운 Access Token을 헤더에 실어 다시 API 요청을 진행한다.
이 방식의 장점은 Access Token만 있을 때 보다 보안상 더 안전하다는 것이다. 단점으로는 구현이 복잡해지고 서버의 자원낭비가 심하다는 점이다.
Session 관리 대안으로 JWT, AccessToken + Refresh Token 두 가지 방안을 알아봤는데, 두 방법 모두 Vue, Spring Boot를 활용한 인증 방식중 많이 사용되는 방식들이다. 서버의 자원 상황이나, 보안 필요사항을 고려하여 인증 방식을 선택하여 개발을 하면 될 것이다.
'Programing & Coding > Promgraming Concept' 카테고리의 다른 글
SOA 패턴이란? (0) | 2023.02.07 |
---|---|
CBD 개발 방법론 (0) | 2023.02.07 |
GitLab GitHub 100M 넘는 레포 옮기기 (0) | 2021.10.16 |
API - 필수 파라미터 살펴보기 (0) | 2020.07.09 |