작년 프리온보딩 챌린지 당시 강의 내용을 정리하고 요약해뒀던 글이다. 굉장히 유익했던 강의라 shoveling 레포에 기록해두었는데, 벨로그에 올리는 걸 까먹었어서 다시 정리해보았다.
사용자가 시스템에 접근하거나 동작을 수행하는 것을 제어하고 기록하기위한 컴퓨터 보안절차
사용자를 식별하기 위해
http 요청이라는 것은 단지 텍스트 요청이며 무상태성을 유지해야하기 때문에 알수 없음.
일단 이렇게만 해도 굴러가긴 한다.
실제 서비스에서의 구조 (*액세스 토큰만 사용한다는 가정)
검정 박스가 클라이언트 단에서 처리하는 부분
JSON web token
json 기반 웹에서 사용하기 위해 만든 토큰
암호화를 위한 데이터
특정 문자열 : 서버에서 해당 jwt 가 유효한지 확인 해보는 용도
왜 이러한 문자열인지는 알 수가 없음. 해싱이기 때문
secret key는 서버가 만들어서 클라이언트는 알 방법이 없음.
헤더와 페이로드는 언제나 클라이언트에서 열어볼 수 있다. 하지만 이 두가지로는 만들 수 없는 조각을 주는 것(시그니처)
시그니처에 서버가 자신이 준것이 맞는지 확인해볼 수 있는 시크릿 키가 맞는지 해싱을 다시 돌려서 해시로 나온 값과 동일한지 확인 할 수 있다 (= 올바른 유저인지)
서버에서는 암호화되지 않은 secret key가 있고, 시그니처에서는 암호화된 secret key를 가지고 있다.
실제로 JWT 관련 동작이 일어나는 곳
클라이언트 - 토큰 탈취
-> 토큰이 유효한 시간 동안 로그인이 모두 가능한 상태됨..
서버- 시크릿 키 노출
-> 토큰을 무한하게 찍어낼 수 있는 상황이 발생함
어떤 사용자의 이름, 이메일 등 사용자정보를 무한히 찍어낼 수 있게 되는 것
클남..
서버입장에서는 문자열(토큰) 하나면 유저 확인을 언제든 가능함.
클라이언트 사이드에서는 사실 이득도 업다.. 해달라고 하면 되기에 딱히 단점도 없다..
서버에서는 매번 확인하는게 아니라 요청이 들어올때만 유효성을 알려주면댐
토큰 하나에 시크릿키 하나면 유효 여부, 유효에 대한 기간, 정보들을 모두 알 수 있다.
Refresh token & Access Token 사용하기
리프레시 토큰은 발급은 하는데, http only 쿠키로 발급
보통 그렇기에 인증 필요한 api 호출시 보통 2개의 api가 전송됨
(토큰 유효한지 체크 api + 해당 토큰으로 받아오는 정보 api)
<정리 ~! >
1. 로그인 요청
2. 리스폰스 값 : 액세스와 리프레쉬
3. 메모리에 저장된 액세스토큰으로 요청
4. 액세스 토큰이 만료가 됨
5. 리프레쉬 토큰으로 다시 액세스 토큰 재요청
6. 메모리에 저장된 재요청한 액세스 토큰을 헤더에 담아 정보 요청
스토리지 ? 저장소
로그인 행위 되돌아보기
사용자가 누군가인지 식별하기 위해 로그인을 사용, 그 수단으로 토큰을 사용함.
세션은 연결 자체의 이름, 사용자의 로그인해서 로그아웃, 혹은 만료까지의 기간(커넥션)
세션 방식 로그인 : 사용자 로그인이 유효한 시간동안 서버에 세션 아이디를 기록하고 인증에 사용하는 방식
서버에서 보내주는 작은 데이터 조각, 클라이언트에게 setCookie 와 같은 리스폰스 헤더에 담아 전달,,
같은 도메인에 보낼때 그 쿠키를 자동으로 붙여서 보낸다.
실제로 브라우저에서 어떻게 동작?
쿠키는 직접 넣어주는 값이 아니다. 프론트에서 직접 할 일은 없다.
SamSite
httpOnly
Secure
https : 인증서 기반 암호화 - 패킷의 암호화가 올바른 경우에만 sameSite lax가 동작
로컬호스트는 보통 http -> CORS 오류 자주 발생, 403 밴 당하는 경우도 종종 발생
CORS란 오리진이 다른 두경우(도메인이 다른 두개) 서로 api를 찔러서 가져가는 경우를 차단 해둔당..
에러 해결방법
세션 아이디를 쿠키에 담아 credential true로 주면, 자동으로 왔다갔다 ~
: 4000에 서버, :5173에 클라 띄워서 같은 로컬 pc에서 구성함
동시 접속자 수, 서비스 규모, 앱/웹 동시운용 여부, 팀내 인력 구성 등등... 을 이유로 선택은 서비스 상황에 따라 결정
앱/웹... 동시 사용시에는 토큰 많이 사용,, 뭐 프론트가 굉장히 많은 경우 토큰 사용하거나 ~ 백이 많으면 세션을 쓰는게 유리하다고 생각 둘다 없으면 뭐 화이팅 ㅋㅋㅋ..이러네
프로토콜
하이퍼 텍스트 -> 누르면 이동하는 문서
Bearer
cURL
프론트의 코드는 브라우저에 노출되기 때문에 보안 관련된 역할 분담은 서버에게 확실히 이야기 할 필요가 있다 (서버 벨리데이션은 필수적이다)
그 다음 프론트에서 할 일 -> 권한에 따라 적절한 자원에 접근하도록 하기
ex) 유저에게 role이 주어져있는게 없다면 로그인 으로 routing , 뭐 빈 컴포넌트 리턴
http 401 에러 ( 누구세요) 에 대한 문제 해결 - > 리프레시 토큰으로 엑세스 토큰 재발급 시도 (무한루프 가능성 있는 코드임 - 리프레시 토큰에 의해 401이 해소되지 않는경우에 발생가능함 , retry 카운트 만드는걸루 해결해볼 수 있음(윈도우 객체에다가 Number해도 되고, axios 인스턴스 안에다가 만들어두됨))
요청을 시도하다가 요청이 실패한 경우에 임시신분증,,,(리프레시 토큰)으로 액세스 토큰 재발급 시도
재발급 실패 -> 로그인 페이지로 보냄
(**수정사항 2번째꺼는 마지막 구문 삭제)
1.로컬스토리지에 저장하는 경우
2. 세션에 쿠키에다 저장하는 경우
리프레시 토큰은 항상 1회용이고 액세스 할때마다 새로운 엑세스, 리프레시 토큰이 매번 세팅이 되는 방식으로 구현
refresh token
Open Authorization
허가된 다른 서비스를 통해 기존 서비스(구글, 네이버 등) 의 권한을 "위임"하는 것
기본적으로 개별 서비스(배민..이라구 하고~)가 있고, 원본 서비스가 존재한다.
1. 구글로 로그인 클릭 -> 개별 서비스가 링크를 하나로 주고, 구글한테 확인받고 오라고 리디렉션
2. 구글페이지에서 배민에서 구글게정으로 이런저런 동작하고 싶어요, => 이런저런 동작은? : 링크에 쿼리파라미터로 확인
3. 구글: 시크릿값을 주고, 주소 A로 이동하세요 , 구글 또한 보관
4. 구글 다녀옴, 시크릿값도 있고, 주소 A 도착 : 배민이 구글에게 시크릿값과 주소 A로 접근했다는 걸 확인 받음
권한에 따라 오어스 원본 서버의 유저정보를 가져와 사용하거나 권한을 위임받은 동작도 할 수있으며, 인증 자체만으로 사용할수도 있다!
클라이언트가 구현해야할 동작
1. 리디렉션
2. 요청이 승인 되었을때 : 로그인을 기록해둘 방법이 필요, 세션이든 토큰이든 ~
서버입장 : 시크릿키도 챙기기, 배민-구글 간의 시크릿키도 갖고있기
~ 추가 공부
싱글톤 패턴
객체를 다루지 않는 프엔 트렌드 특성상 생소할 수있음 프론트에 없는 컨셉일지두..
하지만 우리가 구현한 것중에 비스무리한게 하나 있담.
하나의 데이터 오리진을 가지고 필요한 동작들을 수행하는 것
ex - 라우터 객체
사이드바에도 쓰이고, 페이지 라우터에도 쓰였음. 핵심은 이 데이터가 한가지라는 것.
데이터의 원천 생각하기
하나의 데이터가 하나의 맥락에서 관리되고 있는가?
백엔드도 처음이라면 모를 수 있어요
FormData < Json
멀 사용해도 상관 ㄴㄴ