Cookies Session JWT bcrypt

HTTP 특성

HTTP는 비열결성 및 무상태성이라는 특징을 가진다. 요청에 대한 응답을 처리하게 되면 연결을 끊어버린다. 만약 서버가 다수의 클라이언트와 연결을 계속 유지한다면, 이에 따른 자원 낭비가 증가하기 때문에, 비연결성과 무상태성의 특징으로 불필요한 낭비를 줄일 수 있다.

하지만 이러한 특징은 클라이언트를 식별할 수 없다는 단점으로 이어진다. 로그인을 하더라도 다음 요청에서 클라이언트를 기억하지 못해 다시 로그인을 해야하는 문제가 발생한다.

이러한 HTTP의 비연결성과 무상태성 특징을 보완한 기술이 Cookie와 Session이다.

🍪 Cookie & Session 기반 인증

쿠키를 통해 클라이언트 로그인 상태를 유지시킬 수 있었지만, 가장 큰 단점은 쿠키가 유출 및 조작 당할 위험이 존재한다는 것이다. 개인정보를 HTTP로 주고 받는 것은 위험하다.

세션은 비밀번호 등 클라이언트의 인증 정보를 쿠키가 아닌 서버 측에 저장하고 관리한다.

Cookie & Session 인증 과정

  • 서버는 클라이언트의 로그인 요청에 대한 응답을 작성할 때, 인증 정보는 서버에 저장하고 클라이언트 식별자인 JSESSIONID를 쿠키에 담습니다.
  • 이후 클라이언트는 요청을 보낼 때마다, JSESSIONID 쿠키를 함께 보냅니다.
  • 서버는 JSESSIONID 유효성을 판별해 클라이언트를 식별합니다.

🔑 JWT 기반 인증

JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 토큰을 의미한다. JWT 기반 인증은 쿠키/세션 방식과 유사하게 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별한다.

JWT 설치

npm i jsonwebtoken

JWT 간단한 사용 예시

JWT 구조


JWT는 .을 구분자로 나누어지는 세 가지 문자열의 조합이다. 실제 디코딩된 JWT는 다음과 같은 구조를 지닌다.

Header


Header는 alg과 typ는 각각 정보를 암호화할 해싱 알고리즘 및 토큰의 타입을 지정한다.

payload


Payload는 토큰에 담을 정보를 지니고 있다. 주로 클라이언트의 고유 ID 값 및 유효 기간 등이 포함되는 영역이다. key-value 형식으로 이루어진 한 쌍의 정보를 Claim이라고 칭한다.

signature


Signature는 인코딩된 Header와 Payload를 더한 뒤 비밀키로 해싱하여 생성한다. Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없다. 따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용된다.

JWT 인증 과정

  • 클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보낸다.
  • 아이디/비밀번호가 일치하는지 확인하고, 클라이언트에게 보낼 암호화된 토큰을 생성한다.
    • access/refresh 토큰을 모두 생성한다.
    • 토큰에 담길 정보(payload)는 유저를 식별할 정보, 권한이 부여된 카테고리(사진, 연락처, 기타등등)이 될 수 있다.
    • 두 종류의 토큰이 같은 정보를 담을 필요는 없다
  • 토큰을 클라이언트에게 보내주면, 클라이언트는 토큰을 저장한다.
    • 저장하는 위치는 local storage, cookie, react의 state 등 다양하다.
  • 클라이언트가 HTTP 헤더(authorization 헤더)에 토큰을 담아 보낸다.
    • bearer authentication을 이용한다.
  • 서버는 토큰을 해독하여 "아 우리가 발급해준 토큰이 맞네!" 라는 판단이 될 경우, 클라이언트의 요청을 처리한 후 응답을 보내준다.

🛡 bcrypt

패스워드를 안전하게 보관할 수 있도록 패스워드를 해시하는 알고리즘.

단방향 암호화를 위해 만들어진 해시 함수

해시(hash)란 단방향 암호화 기법으로 해시함수(해시 알고리즘)를 이용하여 고정된 길이의 암호화된 문자열로 바꿔버리는 것을 의미한다.

복잡도가 증가할 수록 hash하는데 걸리는 시간이 기하급수적으로 증가한다.

bcrypt

bcrypt의 값은 4부분으로 나눠진다

i) Algorithm : 알고리즘 식별자. '2a2a'는bcrypt를 뜻한다
ii) Cost factor : 키 스트레칭한 횟수. 2^n으로 위의 경우 2^10=1024이다
iii) Salt : 128비트 솔트, 22자 base64로 인코딩
iv) Hash : salting과 키 스트레칭 후 해시 값

bcrypt 설치

npm i bcrypt

import bcrypt from 'bcrypt';

const password = 'abc123';
const hashed = bcrypt.hashSync(password, 10);  //<<<--- 8~12 정도를 추천
console.log(`password: ${password}, hashed: ${hashed}`);

const result = bcrypt.compareSync('abc123',hashed)
console.log(result)  //<<<--- true

결과

password: abc123, hashed: $2b$10$u/DefTQGmF7GT4KM5tSoduSq6O4QB33nCeQYvfo3.Q.YRZE4X7va.

true

참조)
인증방식 : cooke session JWT

좋은 웹페이지 즐겨찾기