내가 만든 쿠키(Cookies)
세션, 토큰 저장 용도지~
안녕하세요. 오딘(Odin)입니다.
여러분 개발하다보면 쿠키, 세션, 토큰이라는 단어를 많이 들어보셨을거예요.
"세션, 토큰을 쿠키에 저장해라!", "토큰을 다시 받아라!" 라는 글을 가끔 보는데
근데 이게 뭘까요?? (먹는 쿠키는 아는데... 🍪)
앱 개발로 처음 개발을 시작하신 분이라면
쿠키를 사용할 일이 거의 없다보니 이러한 정보를 알고 계시기 어려우실 겁니다.
그러면 우리 같이 쿠키, 세션, 토큰에 대해서 공부해볼까요?!?
쿠키, 세션, 토큰 왜 필요한가??
클라이언트와 서버는 데이터를 주고 받기 위해
가장 범용적으로 사용되고 있는 HTTP 프로토콜 방식을 사용하고 있고 다음과 같은 특징이 존재합니다.
HTTP 프로토콜
- 비연결성지향(connectionless)
- HTTP는 먼저 클라이언트가 요청을 서버에 보내면, 서버는 클라이언트에게 요청에 맞는 응답을 보내고 TCP/IP 연결을 끊는 특성이다.
- HTTP 1.1에서는 헤더에 keep-alive라는 값을 줘서 커넥션을 재활용한다
- 무상태(stateless)
- 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보를 유지하지 않는 특성이다.
즉, 로그인을 했더라도 요청, 응답이 끝났기 때문에 다음 화면으로 이동시 유저가 로그인한 동일 인물인지 알지 못합니다.
이러한 HTTP 프로토콜의 한계를 보안하기 위해 쿠키, 세션, 토큰을 사용한다고 생각하시면 됩니다.
쿠키(Cookies) 란?
- 사용기록을 저장해 두는 임시 파일
특징
- 쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일 (약 4KB)
- Response Header의 set-cookie 속성에 정보를 담을 수 있음
- 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 전송
- 장바구니, 사이트 내 검색 내역, 팝업 설정 등 간단한 데이터를 저장해 두는 용도로 사용
- 쿠키의 구성 요소
- 이름(Name) : 각각의 쿠키를 구별하는 데 사용되는 이름
- 값(Value) : 쿠키의 이름과 관련된 값
- 유효시간(Expires) : 쿠키의 유지시간
- 도메인(Domain): 쿠키를 전송할 도메인
- 경로(Path): 쿠키를 전송할 요청 경로
(다음과 같이 Header 내부에서 Cookie를 찾아 볼 수 있습니다!!)
🤷🏻♂️ : 아니 그래서!!
iOS 개발할 때 쿠키는 쓰이긴 하는거야??
나는 사용해 본적이 없걸랑?!
맞아요~ 쿠키는 웹에서 주로 사용하는 용어로
개발을 iOS로 처음 입문 하셨다면 쿠키(Cookies)를 사용할 일이 거의 없었을 겁니다.
그러나 앱(App) 에서 웹(Web) View를 띄워 넘어가는 화면을 종종 보신적이 있으실 겁니다.
(UIWebView, WKWebView, SFSafariView)
그렇다면 여기서!!
만약 유져가 로그인한 상태로 앱에서 웹의 마이페이지로 넘어가는 경우가 발생한다고 해봅시다.
여러분들은 로그인한 정보를 넘겨 주어야 할 탠데 어떻게 넘겨 주실건가요??
오호.. 이제 조금 감이 오시나요?! ^ㅇ^
iOS +11 이상부터 사용이 가능한 WKWebsiteDataStore 의 간단한 예제를 보자면
let cookie = HTTPCookie.init(properties: [
.domain : 도메인,
.path : 경로,
.name : 쿠키 이름,
.value : 쿠키 값,
...
])
WKWebsiteDataStore.default().httpCookieStore.setCookie(cookie!, completionHandler: {})
다음과 같이 쿠키에 다양한 정보들을 저장하고 이를 활용하여
WebView에 마이페이지를 띄울 수 있게 되는 것입니다.
iOS에서 UserDefults랑 비슷하게 저장하는 작은 데이터 역할 한다고 생각하시면 됩니다!!
(그러나 동일시 하시면 안됩니다!! 웹에도 로컬 스토리지 라는게 존재하니!!)
⛔️ 주의!!
그렇다고 모든 장바구니, 토큰에 대한 정보를
쿠키에 저장하는 것은 아닙니다!!
마켓 컬리를 예를 들어서 확인해볼까요??
로그인 하지 않은 상태에서 마켓 컬리의 장바구니를 살펴보았어요!
오잉?!?
쿠키(Cookies) 가 아닌
로컬 스토리지(Local Storages)에 저장하고 있네요!!
로컬 스토리지는 쿠키보다 더 큰 용량의 데이터를 저장 할 수 있는 공간입니다.
또한 세션 스토리지라는 공간도 존재한답니다.
그리고 꼭 이렇게 로컬 저장공간에만 저장하지는 않아요!!
가상의 user를 만들어 익명 로그인 방식으로 서버에 정보를 저장하기도...😅
한마디로 해당 정보를 어디에 저장할지에 대한 권한은
서버 개발자 마음이랍니다. ^ㅡ^
그러니 쿠키가 어떤 것인지만 알아가는걸로~!!ㅎㅎ
근데 "내가 로그인 했다" 라는 정보를 넘겨준다고 했는데
매번 아이디와 비밀번호를 넘겨주어 로그인 상태를 체크하는 것은
너무 불필요한 작업일탠데...
그러면 이 정보는 어떻게 넘겨주는 것일까요??
세션(Session) 이란?
- 같은 사용자로 부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술
(서버와 클라이언트의 연결이 활성화된 상태)
동작원리
1) 클라이언트는 아이디, 비밀번호를 서버에게 전달 (로그인)
2) 서버에서 새션을 생성 후 세션 ID를 클라이언트에게 전달 (서버는 세션 ID를 통해 식별)
3) 클라이언트는 세션 ID를 쿠키에 저장하고 서버에 해당 로그인시 식별자 용도로 사용
4) 클라이언트 종료 (브라우저 종료)시 세션 ID 제거, 서버에서도 세션 제거
특징
1) 세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리
2) 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여
3) 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지
4) 물론 접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정이 가능
5) 클라이언트가 Request를 보내면 각 클라이언트마다 유니크한 세션 객체가 주어지고, 이 세션 객체에 데이터를 담아 관리 할 수 있음
(세션 객체가 자물쇠로 잠긴 상자라면 세션 ID 가 열쇠)
위에서 알 수 있듯이 세션은 로그인한 유져가 브라우저를 종료하기 전까지 항시 메모리에 올라가 있답니다.
아니.. 사용자가 1000명... 10000명이 넘어가도 브라우저를 종료하기 전까지 메모리에 올라와 있다면
메모리 공간이 부족해지고 서버에 부하가 걸릴텐데...
이거 너무 비효율적인거 아니야?? 😱😱
토큰(Token) 이란?
- 로그인 요청시, 어떠한 데이터를 기반으로 인증이 가능한 토큰(난수 문자열)을 만들어서 클라이언트에 전달하는 방식
(해당 토큰에 대한 유효성을 검사하여 사용자가 인증 되었는지 판단)
동작원리
1) 클라이언트는 아이디, 비밀번호를 서버에게 전달 (로그인)
2) 서버에서 세션을 이용해서 정보를 기록하는 대신, 알고리즘을 통한 Token을 발급
3) 클라이언트는 토큰을 Local Storage에 저장하고, 서버에 해당 로그인시 header에 포함시켜 보냄
4) 서버는 매 요청시, 클라이언트로 부터 전달받은 Header의 토큰 정보를 검증한뒤 해당 유저에게 권한을 인가한다.
특징
1) 클라이언트에 저장되기 떄문에 서버의 메모리에 부담이 되지 않음
2) 멀티 디바이스 환경에 대한 부담이 없음
3) 세션 인증에서는 서버가 세션 ID를 저장하고 클라이언트가 쿠키에 실어 보낸 세션 ID와 대조해서 확인하는 반면,
토큰은 서버에서 유효값(True/ false) 만을 확인하면 되어 세션 인증에 비해 서버 운영의 효율이 더 좋음
🤷🏻♂️ : 오호 그렇다면 토큰이 무조건 좋겠네요!?
🙅🏻♂️: 삐이이익!!(X)
그렇지 않습니다.
엥...??
토큰(Token) vs 세션(Session)
아니 세션은 메모리에 항상 올라오고 토큰은 메모리에 올라가지 않아서
메모리적으로 봤을 때 훨씬 더 효율적인거 같은데 왜 토큰이 더 좋은게 아닌건가요?!?
네 그렇죠.
세션은 로그인 상태를 메모리에 항상 올려둔다고 했습니다.
그러나
넷플릭스를 예를 들어 보겠습니다!!
넷플릭스는 사용 가능 인원이 정해져 있는 플랫폼입니다.
그런데 만약 다양한 기기에서 동일한 User가 동시에 접속을 한다면?!
한 곳을 제외한 다른 Device에서 로그아웃 처리를 해주어야 할 것입니다!
이럴 때 필요한게 세션 방식입니다.
세션 방식은 로그인한 유저를 세션 객체를 만들어 서버에 올려두기 때문에
로그인한 유저를 찾아 실시간으로 Block시킬 수 있기 떄문이죠!!
그러니!!
좋고 나쁘다는 이분법 적인 사고에 둘러 쌓이지 마시구
상황에 맞게 잘 적용하는 개발자가 되어야 겠죠~?!ㅎㅎ
참조
'iOS' 카테고리의 다른 글
[iOS] Firebase Auth (파이어베이스 인증) 전화번호 인증 처리 (0) | 2022.12.12 |
---|---|
[iOS] Firebase 를 활용한 push 알림 (Remote Notification) (0) | 2022.10.14 |
[iOS] Firebase 를 활용하기 & crashlytics 분석하기 (1) | 2022.10.11 |
[iOS] 미히 - May I help youth? (청년 지원 정책 Service) - 회고(1) (0) | 2022.10.05 |
[iOS] App SandBox란? (0) | 2022.08.29 |