Spring에서 인증과 인가를 관리해주는 대표적인 것은 Spring Security
인증(Authentication) : 해당 유저가 실제 그 유저인지 인증하는 개념. 지문인식, 로그인.
인가(Authorization) : 해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념
관리자페이지 - 관리자 권함
일반적으로 서버-클라이언트 구조로 되어있고 두 요소는 아주 멀리 떨어져 있다.
HTTP 프로토콜을 이용해 통신하는데 비연결성(Connectionless) 무상태(Stateless)로 이루어진다.
비연결성 : 서버와 클라이언트가 연결되어있지 않다. 채팅 게임 같은것이 아닌 이상 서버와 클라이언트가 계속 연결된 상태가 아니다. 계속 연결되어있으면 비용이 급격하게 늘어난다.
서버는 실제로 하나의 요청에 하나의 응답을 하고 연결을 끊는다.
무상태 : 서버가 클라이언트의 상태를 저장하지 않는다. 기존의 상태를 저장하는 것은 서버의 비용과 부담을 증가시킨다. 그래서 기존의 상태가 없다고 가정하는 프로토콜을 이용해 구현되어 있다. 서버는 클라이언트가 그 전에(혹은 직전에) 어떤 요청을 보냈는지 관심도 없고 알지도 못한다.
비연결성 무상태이더라도 url을 계층적으로 설계하고 인증 방식을 잘 설계한다면 클라이언트가 느끼기엔 이전의 정보들이 연속성있게 잘 있는 것처럼 느끼게 할 수 있다.
- 사용자가 로그인 요청을 보낸다.
- 서버는 DB의 유저 테이블을 뒤져서 아이디 비밀번호를 대조해본다.
- 실제 유저테이블의 정보와 일치한다면 인증을 통과한 것으로 보고
세션 저장소
에 해당 유저가 로그인 되었다는 정보를 넣는다.- 세션 저장소에서는 유저의 정보와는 관련 없는 난수인
session-id
를 발급한다.- 서버는 로그인 요청의 응답으로 session-id를 내어준다.
- 클라이언트는 그 session-id를
쿠키
라는 저장소에 보관하고 앞으로의 요청마다 세션아이디를 같이 보낸다. (주로 HTTP header에 담아서 보낸다)- 클라이언트의 요청에서 쿠키를 발견했다면 서버는 세션 저장소에서 쿠키를 검증한다.
- 만약 유저정보를 받아왔다면 이 사용자는 로그인이 되어있는 사용자로 간주한다.
- 이후에는 로그인 된 유저에 따른 응답을 내어준다.
쿠키-세션 방식은 서버가 특정 유저가 로그인 되었다는 상태를 저장하는 방식
인증과 관련된 아주 약간의 정보만 서버가 가지고 있고 유저의 인증과 관련된 최소한의 정보는 저장해서 로그인을 유지시킨다.
쿠키와 세션 모두 HTTP에 상태 정보를 유지(Stateful)하기 위해 사용된다.
: 클라이언트에 저장될 목적으로 생성된 작은 정보를 담은 파일
쿠키의 구성요소
Name (이름) : 쿠키를 구별하는데 사용되는 키(중복 불가)
Value (값) : 쿠키의 값
domain : 쿠키가 저장된 도메인 / path : 쿠키가 사용되는 경로 / expires : 쿠키의 만료기간
특징 : 클라이언트의 웹 브라우저에 저장된다. 용량제한은 브라우저별로 다르며 하나의 쿠키당4KB. 보안이 취약하다 (클라이언트에서 쿠키정보를 쉽게 변경, 삭제 가로채기 가능)
: 서버에서 일정시간동안 클라이언트의 상태를 유지하기 위해 사용
서버에서 클라이언트 별로 유일무이한 세션ID를 부여 후 클라이언트 별 필요한 정보를 서버에 저장
서버에서 생성한 세션ID는 클라이언트의 쿠키값(세션쿠키)으로 저장되어 클라이언트 식별에 사용된다.
- 사용자가 로그인 요청을 보낸다.
- 서버는 DB의 유저 테이블을 뒤져서 아이디 비밀번호를 대조해본다.
- 실제 유저테이블의 정보와 일치한다면 인증을 통과한 것으로 보고 유저의 정보를 JWT로 암호화 해서 내보낸다.
- 서버는 로그인 요청의 응답으로 jwt 토큰을 내어준다(주로 헤더에).
- 클라이언트는 그 토큰을 저장소(보통 쿠키저장소)에 보관하고 앞으로의 요청마다 토큰을 같이 보낸다.(API 요청시 마다 Header에 포함)
- 클라이언트의 요청에서 토큰을 발견했다면 서버는 토큰을 위조 검증(Secret Key 사용)한다.
- 이후에는 사용자 정보를 가져와 확인하고 로그인 된 유저에 따른 응답을 내어준다.
사용이유 : 서버가 여러대인 경우 각 서버마다 세션 저장소를 가지면 로그인 정보 매칭이 안될 수 있음. 로그인 정보를 서버에 저장하지 않고 JWT로 암호화 해 따로 저장.
모든 서버에서 동일한 Secret Key를 소유해서 암호화 - 위조검증 가능.
장점 : 동시접속자 많을 때 서버 부하 낮춤(서버에 저장하지 않고 브라우저에 저장했다가 Secret Key로 위검증만 하기때문에 부하가 낮다.)
클라이언트/서버가 다른 도메인을 사용할 때 사용하기 쉽다.(ex. 카카오 OAuth2)
단점 : 구현 복잡도 증가. Secret Key 유출시 JWT 조작 가능.
JWT에 담는 내용이 커질수록 네트워크 비용 증가(JWT가 생각보다 길어 용량 많이 차지할수도)
이미 생성된 JWT를 일부만 만료시킬 방법이 없다.
암호화 알고리즘에 의해 '.'을 사용해 3부분으로 나뉘어져 암호화 되어있다.
가운데에 실제 유저의 정보가 있고 HEADER와 와 아래부분은 암호화 관련 정보 양식이다.
누구나 평문으로 복호화 가능하지만 Secret Key가 없으면 수정이 불가능하다. ReadOnly데이터!