2022-03-16 T.I.L 인증/보안

정종훈·2022년 4월 1일
0

T.I.L

목록 보기
13/20

인증/보안 기초 성취목표


이번 스프린트에서는 특정 서비스를 완성하는 과정을 통해, 2가지 주제를 집중적으로 학습하게 됩니다.

회원 가입 및 로그인, 로그아웃과 같은 기능을 구현하게 됩니다. 이와 더불어 큰 개념인 인증(authentication)에 대해서 알아봅니다.
클라이언트, 서버, 데이터베이스 모두를 다루면서, Full Stack 개발 환경에서의 전체적 흐름 및 작동을 직접 확인합니다.
Achievement Goals
암호화와 hashing, salting 등의 개념을 이해할 수 있다.
HTTP와 HTTPS의 차이점을 이해할 수 있다.
권한 부여(Authorization)와 인증(Authentication)에 대해 이해할 수 있다.
쿠키의 작동 원리를 이해할 수 있다
세션 및 쿠키 / 토큰 / OAuth를 통해 인증 구현을 할 수 있다.
클라이언트, 서버, 데이터베이스의 전체 동작을 이해할 수 있다.
회원가입 및 로그인 등의 유저 인증에 대해 구현하고 이해한다.
서비스의 보안과 관련된 방법을 알아보고 원리 및 장점 및 단점을 이해한다.

HTTPS


Hyper Text Treansfer Protocol Secure Socket layer의 약자

HTTP 프로토콜 내용을 암호화 어떻게? => SSL, TLS 알고리즘

SSL : Secure Sockets Layer; 구글에서 2018년 부터 SSL 인증서가 포함되어있지 않은 사이트를 방문할때 '안전하지 않음' 을 띄워 처벌함.

TLS : Transport Layer Security; 강력한 버전의 SSL임

기존의 HTTP는 요청을 쉽게 가로채서 정보를 볼 수 있었는데

HTTPS는 인증서, CA, 비대칭 암호화를 통해 정보를 암호화!!

아니 근데 HTTPS 왜 씀?

  • 클라이언트는 데이터 제공자가 제공해 준 데이터를 사용할수 바에 없음

  • 근데 중간에서 가로채는 중간자 공격에 취약함

HTTP 패킷을 분석했을때 email이 보임

HTTPS 패킷을 분석하면 안보임

  • 그래서 암호화함 !

이에 대해 좀 더 알아보자!

인증서

데이터 제공자 신원을 보장하고 인증서의 내용은 도메인에 종속!

예를 들어 요청을 서버에서 받는다면 서버는 클라이언트에

인증서 도메인과 응답객체 도메인을 보내줌! 그 도메인 2개가 같다면 ㅇㅇ 인정

해커가 만약 중간에서 도메인을 변경하면 이상하다고 알려무!

CA

공인 인증서 발급 기관임!

이 CA의 자격은 지속적으로 갱신됨!

비대칭 키 암호화

RSA 같은 방법임 ㅇㅇ 굳

다만 모든 절차마다 공개키를 사용하면 너무 연산이 많이 드니까

통신의 처음부분에만 사용됨!!

Hashing

임의의 데이터를 다른 데이터로 매핑! 하는 함수를 해시 함수라고 함!

당연히 비밀번호 같은것을 해시해서 못알아채게 해야 함!

여기에 salt를 추가하는데

salt란 비밀번호에다가 뭔가를 더 추가하여 알고리즘이 뚫리더라도

원본값은 눈치채지 못하게 하는것!

salt는 재사용하면 안되고

유저마다 다르게 salt를 적요해야하므로 salt는 db에 저장해야함!

cookie


아니 HTTP 요청은 무상태성(stateless)라고 하는데

내가 쿠팡에 돌아다녀도 어떻게 우리의 정보가 유지가 될까?

(근데 db에 저장될수도 있지않나?) 쿠키덕분이기도 함

쿠키란?

어떠한 사이트에 들어갔을때 서버가 클라이언트에 일방적으로! 전달하는 작은 데이터

서버가 웹 브라우저에 정보를 전달하는 수단도 되고

반대로 클라이언트에서 서버로 쿠키를 전송하는 것도 포함됨!

근데 그러면 서버가 대체 나에게 무슨 쿠키를 전달하는데?

예를 들어 다크모드 유지, id저장 등등 은 좋지

쿠키에 대한 옵션

document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
  • Domain 옵션
document.cookie = "user=John"

쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 클라이언트에서 쿠키를 전송할 수 있음!

  • Path 옵션
    path=/mypath

서버가 라우팅할 때 사용하는 경로인데
기본적으로는 /임!

예를들어 Path가 /users로 설정되어있고 실제 요청하는 경로가 /users/login이면

여튼 /users는 만족하기 때문에 쿠키 전송이 가능

  • MaxAge or Expires 옵션
> // 지금으로부터 하루 후
let date = new Date(Date.now() + 86400e3);
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;

예를 들어 pc방에서 하루동안 롤 인벤들어가서 로그아웃을 안하고 나왔다..

그러면 서버에서 쿠키에 이 옵션을 주어서 일정 시간 이후 자동 소멸하게 만듦!

  • Secure 옵션
>// (https:// 로 통신하고 있다고 가정 중)
// 설정한 쿠키는 HTTPS 통신시에만 접근할 수 있음
document.cookie = "user=John; secure";

true이면 'HTTPS' 프로토콜을 이용하여 통신하는 경우에만 쿠키 전송 가능

-HttpOnly 옵션

기본적으로 false임!

예를 들어 쿠키는 <script> 태그로 접근 가능해 XSS 공격에 취약하기 때문에

HttpOnly 옵션을 이용해 true로 바꿔 <script> 태그 못 쓰게 함

XSS 공격

크로스 사이트 스크립팅(Cross Site Scripting, XSS) :
공격자가 상대방의 브라우저에 스크립트가 실행되도록 해 사용자의 세션을 가로채거나, 웹사이트를 변조하거나, 악의적 콘텐츠를 삽입하거나, 피싱 공격을 진행하는 것을 말합니다.

  • SameSite 옵션


Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송 여부를 결정함!

Lax :Cross-Origin 요청이면 'GET' 메소드에 대해서만 쿠키를 전송할 수 있습니다.

Strict : Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있습니다.

None: 항상 쿠키를 보내줄 수 있습니다. 다만 쿠키 옵션 중 Secure 옵션이 필요합니다.ㅈ

어떠고 옵션이 많지만 기본적으로

쿠키는 오랜 시간 동안 유지될수있고, JS를 이용해 쿠키에 접근할 수 있기 떄문에

민감한 정보 담지 말자!!

Session


쿠키 인증방식이랑 다른 세션 방식

사용자가 인증에 성공한 상태를 세션이라고 부름!

이때 서버는 사용자가 인증에 성공했음을 알고 있어야 하고

클라이언트는 인증 성공을 증명할 수단을 가지고 있어야 함.

그러면 이제

세션은 서버가 Client에 유일하고 암호화된 ID(세션아이디) 를 부여

중요 데이터는 서버에서 관리

session_id 반환 을 하는데 서버에서 암호화시켜 세션아이디로 저장해 클라이언트에 전달!

그 다음부터는 세션아이디로 필요한 작업을 지속적으로 수행!

만약 로그아웃을 하고 싶다면?

서버의 세션 정보를 삭제하고, 클라이언트 쿠키를 갱신하면 됨!

서버가 클라이언트의 쿠키를 임의로 삭제할 수는 없지만 set-cookie로 세션 아이디의 키값을 무효로 할 수 있음!

근데 이런 세션을 다루려면 귀찮지 않을까? 그래서

express-session

이라는 모듈이 있음. 얘는 미들웨어임

GitHub: express-session

이 미들웨어를 통해 세션에 쿠키를 담거나 여러가지 일을 할 수 있음!



쿠키 방식과 뭐가 다른데?

  • 쿠키는 http의 무상태성을 보완해주는 도구이기만

세션은 접속 상태와 권한 부여를 위해 세션아이디를 쿠키로 전송

  • 쿠키는 클라이언트에 쿠키를 저장하지만

세션은 서버에 정보를 저장

  • 쿠키는 서버에 부담을 덜어줌 왜냐면 클라이언트에 쿠키를 저장하기 때문

세션은 신뢰할 수 있는 유저인지 서버에서 확인가능!


근데 세션의 단점은?

서버 이용자가 매우 많으면 유저마다 정보를 서버에 저장하므로 부하 증가

세션도 여튼 쿠키를 이용하므로 XSS공격으로 인해 쿠키 탈취가능!




자 그러면 세션 스프린트부터 살펴보자!

세션 스프린트(서버구현)


최초의 땅 index.js 부분

  • CORS 정책 설정하기 !!

credentials 부분은 true로 =>

보안상의 이유로 기본적으로 쿠키를 요청으로 보낼 수 없는데

쿠키를 통한 인증을 하려면 일단 요청에 실어서 보내야함 그러기 위해

credentials 부분을 true로 바꿔야함 (XML 기준임. fetch에는 true대신 'include'로)

참조

  • 밑에 부분은 pem 인증서가 있으면 https로 아니면 http로 서버 만드니까

꼭 인증서 복붙하기!!



분기 (routes/user.js)

로그인 구현, 로그아웃 구현, userinfo 구현 3개임!!

하나씩 보자!


로그인 구현(controller/users/login.js)

  • 시퀄라이즈 사용하므로(프로미스 패턴 기반 & ORM(객체 관계 매핑))

async, await 잘쓰기 , findOne 문법 확인!

그것을 userInfo로 확인

userInfo의 여부에 따라 응답해줌!!

로그아웃 구현(controller/users/logout.js)

controller/logout.js (POST /users/logout)
세션 객체에 저장한 값이 존재하면
세션을 삭제합니다. (자동으로 클라이언트 쿠키는 갱신됩니다)

익스프레스 세션을 쓰면 로그인 된 경우 req.session 객체에 userid값으로 정보가 담겼음

그것을 바탕으로 정보가 없으면 400보내주고

정보가 있으면

세션객체의 userId 정보를 삭제해주고

200리턴 왜 post했는데 201이 아니지? 로그아웃이니까?

userInfo 구현(controller/users/userInfo.js)

세션 객체에 저장한 값이 존재하면
사용자 정보를 데이터베이스에서 조회한 후 응답으로 전달합니다.
세션 객체에 저장한 값이 존재하지 않으면
요청을 거절합니다.

저장한 값이 존재하지 않으면 거절
있으면 리턴 끝!@

세션 스프린트(클라이언트 구현)


전체적인 흐름(App.js)

현재 상태(state)는 isLogin(로그인여부), userData가 관리되고 있음.

Mypage 컴포넌트, Login 컴포넌트가 있음.

Login 컴포넌트

저 axios.post 부분은 공부해야함!! 왜 그냥 props.logoutHandler쓰면 안되는지!!

Mypage 컴포넌트

여기서 axios.post보낼때 데이터 null로 안보내면 에러남... 컨텐츠 타입 같은것도 잘 보내주고

profile
괴발개발자에서 개발자로 향해보자

0개의 댓글