인증
서버가 리퀘스트를 보낸 유저가 누구인지 파악하는 기능
먼저 서버에 유저에 대한 정보가 필요하며, 일종의 유저 클래스인 유저 모델이 필요하다.
보통 고유 식별값으로 이메일을 사용하는 추세이고, 비밀번호 같은 경우는 암호화하여 사용한다.
클라이언트에서 회원가입 정보를 전달하면 서버는 이를 확인하고 저장한다. 이후 id 번호를 생성하여 유저를 특정짓는다.
로그인의 경우 서버 URL 로 리퀘스트를 보내면 로그인 값으로 유저를 찾고 비밀번호로 유저가 맞는지 확인한다. 로그인이 성공하면 성공 리스폰스와 함께 문자열(인증서) 값을 보내준다. 이후 해당 문자열을 리퀘스트와 함께 보내며 유저를 알아낼 수 있다.
해당 인증서는 유효기간이 존재하여, 인증서가 만료되면 다시 로그인해야한다.
쿠키 인증
쿠키: 서버 리스폰스나 클라이언트 코드에 따라 브라우저에 저장되는 작은 단위의 문자열 파일
이름, 값, 속성으로 구성된다. 각 속성들은 세미콜론으로 구분된다.
속성에는 만료일, 보안 설정 등이 존재한다.
서버는 리스폰스 값에 Set-Cookie 헤더에 쿠키를 보내준다.
클라이언트는 쿠키를 저장한 후, 이후 브라우저가 리퀘스트를 보낼 때 자동으로 쿠키 라는 헤더에 추가되어 보내진다.
쿠키는 설정된 웹사이트에서만 보내진다. 페이스북이 브라우저에 쿠키를 저장했으면, 페이스북으로는 쿠키를 보낼 수 있지만 구글에는 보낼 수 없다. 그러나 루트 도메인을 공유하는 사이트에서는 보낼 수 있다. google.com , mail.google.com 등에서는 쿠키를 공유할 수 있다.
쿠키의 저장과 전송은 브라우저에서 자동으로 해준다.
쿠키 보안
- Secure : 해당 설정을 추가하면 HTTPS 에서만 클라이언트에서 서버로 쿠키가 보내진다.
- HTTPOnly: 자바스크립트 코드로 쿠키에 접근할 수 없고, 쿠키를 설정한 웹사이트에 리퀘스트로 보낼 수만 있다.
- SameSite: CSRF 를 예방할 수 있는 설정이다. CSRF 는 악성 사이트 B 에서 브라우저에 저장된 쿠키를 통하여 일반 사이트 A로 리퀘스트를 보내는 공격이다. SameSite를 Strict로 하면 다른 도메인에서 리퀘스틑 보낼 때 쿠키가 가는 것을 방지할 수 있다. 하지만 해당 방법은 다소 과한 조치의 느낌이 강하며, 이에 Lax를 설정해줄 수 있다.
- Lax 설정을 하면 링크를 통해 사이트를 직접 방문할 때는 쿠키가 보내진다.
Authorization 헤더 인증
서버는 바디에 인증서를 추가하고, 클라이언트에 보내준다. 이후 JS 코드로 해당 인증서를 직접 저장한다. 이 인증서는 쿠키 혹은 로컬 스토리지에 저장하여 관리할 수 있다.
이후 저장한 인증서를 Header에 Authorization에 붙여 전송한다.
- 리퀘스트에 인증서를 붙일지 안붙일지 선택 가능
- 서로 다른 루트 도메인 사이에서 인증 가능
세션 인증
인증서는 각각 세션과 토큰 2가지 종류가 있다.
세션: 서버가 저장하는 사이트 방문자에 대한 기록
방문자의 ip 주소, 마지막 방문, 브라우저 등 다양한 정보를 저장한다.
이후 세션의 아이디를 쿠키 헤더에 전달하여 쿠키를 통해 인증을 한다.
로그인을 한다면 userId 를 저장하면 된다.
세션 역시 시간이 지나거나 로그아웃을 요청하면 세션이 만료된다.
토큰 기반 인증
인증 토큰을 통하여 리퀘스트를 통해ㅜ 확인한다.
인증 토큰은 유저에 대한 정보를 암호화한 문자열이다. Access Token 이라고도 한다.
유저가 로그인 리퀘스트를 통해 정보가 유효함을 파악하면 서버는 토큰을 만든다. 유저 정보를 토대로 문자열을 암호화하여 암호화된 문자열을 반환한다.
해당 토큰으로 리퀘스트를 보낸다. 보통 헤더에 <Bearer 토큰값>을 저장한다. 해당 토큰으로 리퀘스트를 보내면 서버는 암호화키를 통하여 이를 해석한다.
Refresh 토큰
토큰은 만료 기간이 존재하고, refresh 토큰은 access 토큰이 만료되었을 때 이메일과 비밀번호를 사용하지 않고 access 토큰을 새롭게 발급받는 데 사용되는 토큰이다.
JWT
JSON Web Token
.JSON 형식 데이터를 문자열로 인코딩한 토큰
JWT 토큰은 점을 기점으로 3부분으로 나뉘어져 있다. 헤더, 페이로드, 시그니처이다.
헤더는 토큰 자체에 대한 정보가 저장된다. 암호화 알고리즘 , 토큰 형식 등
이를 baseURL 인코딩한다.
페이로드에는 실제로 저장하려는 정보가 담긴다. 저장하고 싶은 데이터 종류에 제한은 없지만,, 필요한 내용만 간결하게 저장하는 것이 좋다. 또 공식 이름을 최대한 활용한다. (exp, iat, jti)
시크니처에는 토큰의 출처, 신뢰성 등이 작성된다. 헤더와 페이로드를 인코딩한 값과 시크릿 키를 통해 암호화하여 시그니처 값을 만든다.
이를 통해 헤더와 페이로드를 조작하여 악용하는 것을 방지할 수 있다.
인가
리퀘스트가 어떤 권한이 있는지 판단하는 것이다. (무엇을 할 수 있는지)
먼저 인증서를 통해 어떤 유저인지 파악하고(인증), 권한이 있는지 판단한다(인가)
보통 인증 뒤에 인가가 따라온다.