인증(Authentication)
클라이언트가 요청을 했을 때 서버에서 클라이언트의 신원을 확인하는 작업
Http 프로토콜은 기본적으로 무상태성을 갖기 때문에 이전 요청을 기억하지 않는다
-> 쿠키, 세션, 토큰 등의 방식 사용
- key-value로 일루어진 작은 데이터
- 구성 요소
1. key (이름) - value(이름과 관련된 값)
2. 유효시간
Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT
-> 만료일이 되면 쿠키 삭제
Set-Cookie: max-age=3600 (3600초)
-> 0이나 음수를 지정하면 쿠키 삭제
3. 도메인
쿠키 전송 범위 설정(기본은 쿠키가 생성된 서버로만 전송)
4. 경로
path=/ -> /를 포함한 하위 경로 페이지에만 쿠키 전송
5. 보안
secure: 미적용시 http,https / 적용시 https만
httpOnly : XSS공격 방지 / JS에서 접근 불가 / HTTP 전송에만 사용
SameSit: XSRF 공격 방지 / 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송
- 클라이언트가 서버로 요청시, 서버 측에서 클라이언트가 재요청시 필요하다고 생각하는 것을 담아 쿠키를 생성(민감하지 않은 정보를 사용)
- 생성한 쿠키를 header에 담아 전송
- 클라이언트는 서버로부터 발급받은 쿠키를 쿠키저장소에 저장
- 이후 클라이언트가 서버에 요청을 할 때 마다 쿠키를 서버에 전달
- 서버에서 받아 클라이언트를 식별 후 작업
- 장점: 서버의 자원을 사용하지 않기 때문에 서버의 부하가 적음
- 단점: 보안이 취약(쿠키의 값을 그대로 노출) -> 쿠키 내부에는 민감한 정보 X 웹브라우저를 변경할 경우 다른 브라우저에서 저장한 쿠키값 사용 X
쿠키의 용량이 클 경우 네트워크에 큰 부하
- 로그인등 보안 관련 문제를 해결하기 위해 사용
- 쿠키를 사용하지만 쿠키에 민감한 정보를 담지 않고 누구인지 식별할 수 있는 값만 저장(session id)
- 쿠키와 다르게 서버 측에서 session 정보를 메모리나 DB에 저장하여 관리(서버에서 관리)
- 클라이언트가 서버로 로그인 요청
- 서버는 클라이언트가 보낸 id, password를 DB에 저장되어 있는지 확인
- 성공시 key(sessionId)-Value(유저 정보) 형태의 세션을 생성하고
세션 저장소에 저장(메모리 or DB)- 저장한 sessionID만을 쿠키에 담아 전송
- 클라이언트가 sessionId를 담은 쿠키를 header에 담아 요청과 함께 전송
- 서버는 현재 세션 저장소에 클라이언트가 보낸 sessionId를 key로 갖는 세션이 존재하는지 확인 후 요청 수행후 응답
- 장점 : 쿠키에 sessionId만이 존재하기 때문에 네트워크 부하가 적음
서버에서 관리하므로 의심가는 요청일 시 세션저장소에 있는 세션을 삭제 후 다시 로그인 하도록 할 수 있음
민감한 정보가 아닌 sessionid만을 쿠키에 담기 때문에 보안상 유리
서버에 저장되므로 클라이언트의 웹브라우저에 의존하지 않음- 단점 : 로그인한 유저의 정보가 세션에 계속 생성되므로 서버의 부하가 커짐
이를 해결하기 위해 여러 개의 서버를 도입하면 각 서버는 세션을 공유해야함
CORS(Cross-Origin Resource Sharing) 문제
-> 세션을 관리할 때 사용하는 쿠키는 단일 도메인 또는 서브 도메인에서만 사용 가능! -> 여러 도메인에서 사용하기 어려움
- 서버의 부하가 갈 수 있는 세션과 보안 문제가 큰 쿠키의 방식을 개선하여
Statelsess하며 보안 적용이 되어있고, 여러 도메인에서 사용 가능!- 구성 요소
- header : 토큰의 타입과 알고리즘을 지정
{ "alg":"HS256", "typ":"JWT" }
- payload : 토큰에 담을 정보를 포함, 각 key-value쌍을 claim이라 함
claim의 종류 : registered(상호 약속) / private(내가 지정)
--- registered
- iss : 발급자
- sub : 토큰 제목
- aud : 토큰 대상자
- exp : 토큰의 만료 시간
- nbf : 토큰의 활성 날짜(언제부터 활성?)
- iat : 토큰이 발급된 시간
- jti : JWT의 고유 식별자, 중복 처리를 막기 위해 사용
일회용 토큰에 사용하면 좋음{ "iss": "velopert.com", "exp": "1485270000000", "https://velopert.com/jwt_claims/is_admin": true, "userId": "11028373727102", "username": "velopert" }
- signature : header와 payload를 각각 인코딩하여 합친 후 주어진 비밀키로 해쉬를 하여 생성
이 값은 서버에서 관리되는 비밀키가 유출되지 않는 이상 복호화할 수 없음 > 토큰의 위/변조를 확인하는데 사용- 최종 변환 모습
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. - header eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva -payload G4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c - signature
- 장점
- 쿠키와 같이 서버에서 저장하지 않기 때문에 서버의 부하가 적음
stateless를 지킬 수 있음- 특정 도메인에서만 사용할 수 있는 것이 아니기 때문에 확장성이 우수
- 토큰 자체에 토큰의 기본 정보와 전달할 정보, 토큰의 검증 유무를 확인하는 서명이 같이 전달되기 때문에 편리함
- 단점
- 토큰의 길이가 길어 네트워크 부하가 일어날 수 있음
- 암호화가 되었더라도 알고리즘만 알고 있다면 복호화한 값으로 내부의 정보를 볼 수 있다
-> 내부에는 민감한 정보를 담지 말자
-> 필요한 경우에는 payload를 암호화하여 넣어둔다- 토큰을 탈취당할 경우 탈취한 클라이언트가 요청시 서버는 막지 못한다
-> 토큰의 만료시간을 짧게 설정 but 자주 로그인 해야함
-> access 토큰과 refresh 토큰을 사용하여 해결!
- access 토큰
요청시 인증에 사용하는 토큰
만료시간을 짧게 하여 위의 문제점을 해결- refresh 토큰
요청시 access 토큰을 재발급 받기위한 토큰
클리이언트에서 서버로 access 토큰을 보냈는데 만료되었을 때 refresh 토큰을 보내 access 토큰을 재발급
응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. 주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다.
즉, 응용 프로그램이 내부의 세세한 동작 원리를 알 필요 없이 운영 체제나 프로그래밍 언어가 기능을 사용할 수 있게 만드는 도구
쉽게 말하자면 우리가 어떤 API의 기능을 사용할 때 어떻게 구현되었는지, 어떤 원리를 가지고 있는지를 알 필요 없이 그저 API가 제공하는 기능을 갖다가 쓰면 된다!
- 자판기로 예를 들면 우리는 그저 자판기의 내부를 알 필요 없이 먹고 싶은 음료수의 버튼을 클릭하여 받기만 하면 된다!
- public API : 모든 사람이 사용할 수 있는 API
- partner API : 개발한 단체 내부와 그 단체에서 허용한 사람만이 사용할 수 있는 API
- private API : 개발한 단체 내부에서만 사용할 수 있는 API