Authentication - Cookie, Session
HTTPS
http 요청을 SSL 또는 TLS 알고리즘을 이용해 HTTP 통신을 하는 과정에서 내용을 암호화하여 데이터를 전송하는 방법
HTTPS 장점
- 데이터 제공자의 신원 보장
- 암호화된 데이터를 주고받음
- 브라우저가 응답과 함께 전달된 인증서 정보 확인
- 인증서의 도메인과 데이터 전송한 도메인을 비교
HTTPS 특징
- 기밀성: 메세지가 암호화되어 가로챌 수 없고, 읽을 수 없다.
- 무결성: 메세지가 중간에 조작되지 않고 원본 그대로 전달된다.
- 인증서 사용: 도메인을 확인하여 전송자가 맞는지 확인. 서버의 공개키 제공
- 비대칭 키 암호화: 공개 키(메세지 암호화), 비공개 키(암호화된 메세지 복호화)
- SSL / TLS: 웹 서버와 웹 브라우저 간 통신을 암호화하는데 쓰는 프로토콜. TLS가 SSL보다 더 많은 암호화
mkcert로 인증서 발급(macOS)
$ brew install mkcert
$ mkcert -install
// localhost, 127.0.0.1(IPv4), ::1(IPv6)에서 사용할 수 있는 인증서 발급
$ mkcert -key-file key.pem -cert-file cert.pem localhost 127.0.0.1 ::1
Hashing
어떠한 문자열에 임의의 연산을 적용하여 다른 문자열로 변환
3가지 철칙
- 모든 값에 대해 해시 값을 계산하는데 오래 걸리지 않아야 함
- 최대한 해시 값을 피해야 하며, 모든 값은 고유한 해시 값을 가진다.
- 아주 작은 단위 변경이라도 완전히 다른 해시 값을 가져야 함
salt
암호화해야 하는 값에 어떤 별도의 값을 추가하여 결과를 변형하는 것
- 암호화만 하면 해시된 결과가 늘 동일
- 디코딩하여 암호화 해독할 수 있다.
- 원본값에 임의로 약속된 별도의 문자를 추가하여 해시하면 기존의 해시값과 전혀 다른 해시값이 되어 알고리즘이 노출되더라도 원본값을 보호할 수 있다.
- 암호화 하려는 값 + salt = hash 값
주의사항
- salt는 유저와 패스워드 별로 유일한 값을 가져야 한다.
- 사용자 계정을 생성할 때와 비밀번호를 변경할 때마다 새로운 임의의 salt를 사용해서 해싱
- salt는 절대 재사용하지 않아야 한다.
- salt는 db의 유저 테이블에 같이 저장되어야 한다.
Cookie
서버에 클라이언트 데이터를 저장하는 방법의 하나. 단순히 서버에서 클라이언트에 쿠키를 전송하는 것만 의미하지 않고, 클라이언트에서 서버로 쿠키를 전송하는 것도 포함. 데이터를 저장한 이후 아무 때나 데이터를 가져올 수 없고, 특정 조건들이 만족하는 경우(쿠키 옵션)에만 다시 가져올 수 있다.
쿠키 옵션
- Domain: 서버에 접속할 수 있는 이름. 쿠키 옵션에서 도메인은 포트 및 서브 도메인 정보, 세부 경로 미포함.
만약 요청하는 URL이
http://www.localhost.com:3000/users/login
인 경우 도메인은 localhost.com이 된다. 쿠키 옵션에서 도메인 정보가 존재한다면 클라이언트에서는 쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다. - Path: 세부 경로는 서버가 라우팅 할 때 사용하는 경로. 명시하지 않으면 기본적으로
/
path를 전부 만족하는 경우 요청하는 path가 추가로 더 존재하더라도 쿠키를 서버에 전송할 수 있다. path가/users
인 경우/users/login
이어도 쿠키 전송 가능 - MaxAge / Expires: 쿠키가 유효한 기간을 정하는 옵션.
MaxAge
는 앞으로 몇 초 동안 쿠키가 유효한지 설정하는 옵션.Expires
는 언제까지 유효한지Date
를 지정. 이때 클라이언트의 시간을 기준으로 함. 두 옵션이 모두 지정되지 않은 경우 브라우저의 탭을 닫아야만 쿠키가 제거된다. - Secure: 쿠키를 전송해야 할 때 사용하는 프로토콜에 따른 쿠키 전송 여부 결정. 해당 옵션이
true
인 경우HTTPS
프로토콜을 이용하여 통신하는 경우에만 쿠키를 전송할 수 있다. - HttpOnly: 자바스크립트에서 브라우저의 쿠키에 접근 여부를 결정. 해당 옵션이
true
인 경우 자바스크립트에서 쿠키에 접근 불가. 기본값false
. - SameSite: Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송여부를 결정.
- Lax: Cross-Origin 요청이면
GET
메소드에 대해서만 쿠키 전송 - Strict: Cross-Origin이 아닌
same-site
인 경우에만 쿠키 전송 - None: 항상 쿠키 전송. 단 쿠키 옵션 중
Secure
옵션 필요.
- Lax: Cross-Origin 요청이면
쿠키를 이용한 상태 유지
이러한 쿠키의 특성을 이용하여 서버는 클라이언트에 인증정보를 담은 쿠키를 전송하고 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 Stateless한 인터넷 연결을 Stateful하게 유지. But 기본적으로 쿠키는 오랜 시간 유지될 수 있고, 자바스크립트를 이용해서 쿠키에 접근할 수 있기 때문에 쿠키에 민감한 정보를 담는 것은 위험 인증 정보를 탈취하여 서버에 요청을 보낸다면 서버는 누가 요청을 보냈는지 상관하지 않고 인증된 유저의 요청으로 취급.
Session
사용자가 인증에 성공한 상태. 쿠키는 클라이언트에 데이터를 저장하는 방식이지만, 세션은 데이터를 서버에 저장. 쿠키에는 그 데이터에 대한 아이디만 암호화된 상태로 부여.
Cookie vs Session
- | 설명 | 접속 상태 저장 경로 | 장점 | 단점 |
---|---|---|---|---|
Cookie | 쿠키는 그저 https의 stateless한 것을 보완해주는 도구 | 클라이언트 | 서버에 부담을 덜어줌 | 쿠키 그 자체는 인증이 아님 |
Session | 접속 상태를 서버가 가짐(stateful). 접속 상태와 권한 부여를 위해 세션아이디를 쿠키로 전송 | 서버 | 신뢰할 수 있는 유저인지 서버에서 추가로 확인 가능 | 하나의 서버에서만 접속 상태를 가지므로 분산에 불리 |
Session 단점
- 기본적으로 서버의 메모리에 세션정보를 저장. 만약 서버의 이용자가 매우 많은 경우라면 메모리 저장공간의 일정부분을 항상 차지하게 되므로 가용 메모리의 양이 줄어들어서 서버의 성능이 저하되는 현상이 발생.
- 세션은 기존의 쿠키를 완전하게 대체한 것이 아니기 때문에 여전히 쿠키 사용.
- httpOnly 설정이 없는 경우에 쿠키는 악의적인 스크립트 공격(XSS공격)에 취약.
- 세션도 쿠키를 이용하는 것이기 때문에 쿠키의 한계를 그대로 갖는다. 만약 세션아이디 정보가 담긴 정보가 탈취된다면 여전히 개인정보가 유출될 위험이 존재.