[TIL] 웹서비스 인증

이현동·2023년 1월 18일
0

TIL

목록 보기
7/59

인증

인증은 웹서비스를 개발할 때 필수적으로 필요한 기능이다. 사용자마다 원하는 정보, 컨텐츠를 다르기 때문에 이를 다르게 보여주려면 사용자를 인증하는 기능이 필요하고 서버에서는 누구의 요청인지 구분할 수 있어야하기 때문에 요청을 보낸 사용자가 누구인지 단서를 서버에 보내주어야 한다.

인증 방식

웹서비스에서 가장 많이 사용하는 요청방식 중 하나는 HTTP 프로토콜이다.
HTTP 프토토콜 환경은 Connectionless, stateless한 특성을 갖는다.

Connectionless

  • 클라이언트가 요청을 한 후 응답을 받으면 그 연결을 끊음
  • HTTP는 먼저 클라이언트가 request를 서버에 보내면, 서버는 클라이언트에게 요청에 맞는 response를 보내고 접속을 끊는 특성이 있음

Stateless

  • 통신이 끝나면 상태를 유지하지 않음
  • 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성이 있음

위의 두 가지 특성을 해결하기 위해 Cookie와 Session을 사용하게 된다.

  • 쿠키는 클라이언트 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일
  • 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료돼도 인증이 유지됨

쿠키의 동작 방식

  1. 클라이언트가 페이지 요청
  2. 서버에서 쿠키 생성
  3. HTTP 헤더에 쿠키를 포함시켜 응답
  4. 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관
  5. 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄
  6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 때 쿠키를 업데이트하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답

2) Session

  • 세션은 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 서버 측에서 관리하게 된다.
  • 서버에서 클라이언트를 구분하기 위해 SessionID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지
  • 접속 시간에 제한을 두어 일정 시간 응답이 없으면 정보가 유지되지 않게 설정 가능
  • 사용자가 많아질 수 록 서버 메모리를 많이 차지하게 돼서 서버에 과부하를 주게 될 수 있음

Session의 동작 방식

  1. 클라이언트가 서버에 접속 시 SessionID 발급
  2. 클라이언트는 SessionID에 대해 쿠키를 사용해 저장하고 갖고 있음
  3. 클라이언트는 서버에 요청할 때, 이 쿠키의 SessionID를 같이 서버에 전달해 요청
  4. 서버는 SessionID를 전달 받아 별다른 작업없이 SessionID로 Session에 있는 클라이언트 정보를 가져와 사용
  5. 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답

3) Session/Cookie 인증 방식

장점

  1. 쿠키를 매개로 인증을 거치게 되는데 쿠키는 세션 저장소에 담긴 유저의 정보를 얻기위한 열쇠라고 할 수 있기 때문에 계정 정보를 담아 인증을 거치는 방식보다는 안전함
  2. 클라이언트는 고유 ID값을 발급받게 돼서 서버의 자원에 접근 용이

단점

  1. 클라이언트의 HTTP의 요청에서 쿠키도 충분히 훔칠 수 있음

    해결 방안

    • HTTPS를 사용해 탈취해도 정보를 읽기 힘들게 하기
    • 세션에 유효기간 넣기
  2. 세션 저장소를 사용하기 때문에 서버 부하가 높아질 수 있음

2. JWT

JWT는 'Json Web Token'의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다. JWT는 토큰 안에 유저의 정보를 넣는데, 클라이언트 입장에서는 HTTP 헤더에 SessionID나 Token을 실어서 보내준다는 점에서는 동일하지만, 서버 측에서는 '인증을 위해 암호화를 하냐(Token)', '별도의 저장소를 이용하냐(Session)'의 차이가 발생한다.

1) JWT Token

Token을 만들기 위한 3가지 (Header, Payload, Verfy Signature)
1. Header : 위 3가지 정보를 암호화 할 방식(alg), 타입(type) 정보
2. Payload : 서버에서 보낼 데이터 정보 (유저 고유 ID, 유효기간 ..)
3. verify Signature : Base64 방식으로 인코딩한 Header, Payload, SECTRET KEY를 더한 후 서명

2) JWT 인증 방식

장점

  1. 간편하며 별도의 저장소가 필요하지 않음
    • JWT를 발급한 후 검정만 하면 되기 때문
    • Stateless한 서버를 만들 때 강점이며, 서버를 확장하거나 유지, 보수하는데 유리
  1. 확장성이 뛰어남
    • Token을 기반으로 하는 다른 인증 시스템에 접근 가능

단점

  1. 이미 발급된 JWT에 대해서는 돌이킬 수 없음
    Session/Cookie의 경우 해당 Session을 지워버리면 그만이지만, JWT는 유효기간이 완료될 때 까지는 계속 사용 가능

    해결방안

    • 기존의 Access Token의 유효기간을 짧게 하고 Refresh Token이라는 새로운 토큰을 발급
  2. Payload의 정보가 제한적이다. Payload는 따로 암호화하지 않기 때문에 디코딩하면 누구나 정보를 확인 가능

  3. JWT의 길이가 길어서 인증 요펑이 많이질 수 록 서버의 자원낭비 발생

    3. 풀스택 미니 프로젝트에서 사용

    팀원 분들의 구현으로 로그인 기능에 대한 정보를 알 수 있었다. 이번 풀스택미니프로젝트를 통해서 로그인 기능 구현의 종류와 JWT 방식에 대해서 알 수 있었다.

    서버

### 회원가입 ###
pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest() # password 인코딩
db.user.insert_one({'id': id_receive, 'pw': pw_hash}) # user의 ID와 인코딩한 password DB에 저장

### 로그인 인증 ###
# 클라이언트에서 받은 password를 회원가입 때와 같은 방법으로 암호화
pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()

# ID와 암호화된 password를 가지고 해당 유저를 찾음
result = db.user.find_one({'id': id_receive, 'pw': pw_hash})

# 찾으면 JWT 토큰을 만들어 발급
# JWT 토큰에는, payload와 시크릿키가 필요
# 시크릿키가 있어야 토큰을 디코딩(=풀기) 해서 payload 값을 볼 수 있습니다.
# 아래에선 id와 exp를 담았습니다. 즉, JWT 토큰을 풀면 유저ID 값을 알 수 있습니다.
# exp에는 만료시간을 넣어줍니다. 만료시간이 지나면, 시크릿키로 토큰을 풀 때 만료되었다고 에러가 납니다.
payload = {
	'id': id_receive,
	'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=18000) # 토큰의 만료시간 설정
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') # SECRET_KEY를 사용해 인코딩

패키지 : PyJWT, datetime

클라이언트

$.ajax({
	type: 'POST',
	url: '/api/login',
	data: { id_give: id, pw_give: passwd },
	success: function (response) {
		console.log(response);
		if (response['result'] == 'success') {
			// 로그인이 정상적으로 되면, 토큰을 받아옵니다.
			$.cookie('mytoken', response['token']); // 이 토큰을 mytoken이라는 키 값으로 쿠키에 저장합니다.
			alert('로그인 완료!');
         	window.location.href = '/category';
       } else {
			// 로그인이 안되면 에러메시지를 띄웁니다.
           alert(response['msg']);
		}
	},
});

✏️

어렵기만 하고 막막하기만 했던 JWT를 좋은 팀원 분들을 만나 모르는 부분을 물어보고 짜신 코드들을 읽어보면서 많은 것을 배울 수 있는 시간을 가졌습니다 ! 감사합니다 ! :)


참고자료

쉽게 알아보는 서버 인증 1편(세션/쿠키, JWT), 그랩의 블로그
쿠키와 세션 개념, RyanGomdoriPooh

profile
이관중..

0개의 댓글