0928
1. HTTP 프로토콜의 특징
- 비연결 지향(Connectionless) : 클라이언트의 req에 맞는 res를 보낸 뒤 연결을 끊음
- 상태정보유지 안함(Stateless) : 통신이 끝나면 상태정보를 유지하지 않음
=> 기록이 사라져서 어떤 이용자가 요청을 보냈는지 알 수 없음
=> 인증과 권한을 판단하기 어려움
2. 인증(Authentication) 과 권한(Authorization)
1) 인증 (Authentication)
- API 요청에 대하여 사용가능한 사용자인지 확인하는 절차
- 클라이언트가 주장하는 사용자와 동일한 사용자인지를 확인
- 요청의 주체가 누구인지 알기 위해 http 메세지의 Header (Not Body!) 에 인증수단을 넣어 요청
2) 권한 (Authorization)
- 사용자가 특정 자원에 대한 접근 권한이 있는지를 체크
- 클라이언트가 하고자하는 작업이 해당 클라이언트에게 허가된 작업인지 확인
- 사용자의 권한을 레벨에 따라 접근할 수 있도록 제한 가능
- 인증을 거친 후 인증된 사용자에게 특정한 권한을 부여
3. 쿠키 / 세션 / 토큰
- HTTP 프로토콜의 약점을 보완하기 위해 사용 (Connectionless & Stateless)
1) 쿠키 (Cookie)
- req에 대한 res를 보낼 때 쿠키를 함께 보냄
- 쿠키는 단순한 key-value 의 쌍. 클라이언트 로컬에 저장됨
- 일정한 시간동안만 저장되며 클라이언트에는 300개 까지 저장 가능
- 서버로부터 쿠기가 오면 웹브라우저는 쿠키를 저장하고, 요청할 때마다 브라우저가 자동으로 쿠키를 함께 보냄
- 서버는 클라이언트에 사용자가 요청할 만한 정보를 쿠키로 만들어보냄.
- 쿠키는 요청과 응답의 Header에 저장됨
- 브라우저가 종료해도 정보는 남아있음
But 서버가 아닌 클라이언트 로컬에 저장되므로 보안에 취약한 단점
2) 세션 (Session)
- req가 오면 해당 서버엔진이 클라이언트에게 유일한 id인 세션 id를 부여
- 서버에 사용자 정보를 저장(Not 로컬!) 하고, 클라이언트와는 세션 id로만 통신
- 일정 시간동안 같은 브라우저로부터 들어오는 요청을 하나의 상태로 보고 그 상태를 유지 (웹 브라우저 종료시점 까지)
- 클라이언트는 발급받은 세션id를 쿠키를 사용하여 저장
- 세션은 서버 메모리에 저장되며, 서버가 재시작되면 세션데이터가 사라짐 (메모리 리셋)
- 서버자원을 사용하므로 무분별하게 생성하면 메모리 사용량 증가, 속도 느려짐
- 보안성 좋음
3) 토큰 (Token)
- Stateless (무상태) : 클라이언트에 저장하므로 상태를 유지하지 않음
- Extensibility (확장성) : 다른 서비스에서도 권한을 공유할 수 있음
- 유저 인증정보를 서버, 세션, 쿠키에 저장하지 않아 손쉽게 서버 확장이 가능
- 정보를 암호화하여 저장
4. JWT (Json Web Token)
- 인증에 필요한 정보 ( Json 객체 )를 암호화 시킨 토큰
- Access Token 을 http Header에 넣어서 서버로 보냄
- 구조
1) HEADER
- 토큰 타입과 해싱 알고리즘이 들어감(암호화시키는 알고리즘)
1) PAYLOAD
- 토큰에 담을 정보가 들어있음. name과 value로 이루어진 하나의 정보(claim)
- 등록된/ 공개/ 비공개 클레임 존재
- iss:토큰 발급자
- exp:토큰 만료시간
- iat:토큰이 발급된 시간. 토큰의 age가 얼마나 되었는지 판단 가능 =>시간은(numericDate형식)
3) SIGNATUER
- 토큰의 유효성 체크 (secret key 이용)를 위해 서명 검증
- 최초 만들때 signature 에서 scret key를 만드는데 짝퉁은 signature 에서 차단
- Refresh Token
- Access Token(JWT)를 이용한 인증방식은 제 3자에게 탈취당하면 보안에 취약
- 토큰 유효기간이 길면 보안문제. 반대로 짧으면 로그인을 자주해야함..
- refresh token은 Access Token과 똑같은 형태의 JWT(유효기간 2주정도)
- accesstoken이 만료되었을때 새로 발급해줌
- 처음에 로그인 하면 access token과 동시에 발급
5. Token을 이용한 서버 통신 실습
어제 진행한 MongoDB 라우터와 컨트롤러에 추가
1) Jwt를 사용하기위해 모듈화
(1) create : 토큰을 생성하여 return, 매개변수로 payload를 받아온다 (payload는 userId와 name)
(2) verify : 생성한 토큰값을 매개변수로 받아와 암호화를 풀어 return. 에러가 발생하면 에러의 종류에 따라 -1, -2, -3 값을 return
2) 인증이 필요한 작업은 authModule을 만들어 미들웨어로 사용
- Board라는 collection 에 업로드, 수정, 삭제를 할때는 userId와 해당 게시물 작성자 Id가 같아야하므로 이를 인증하기 위함!
- 해더값에 key: Authorization / value: AccesToken값을 넣어 req
- token 에 오류가 있으면 오류의 종류에 따라 에러메시지를 출력하도록 설정.
- userInfo 라는 변수를 만들고 토큰의 decoded 된 userId를 넣음
- 이후 컨트롤러에서 사용을 위하여 함수의 결과를 req에 담고 next로 넘김
3) 이후 Controller에서 해독된 토큰값에 들어있는 userInfo와 mongoDB에 저장된 id가 일치하는지를 확인
4) 일치한다면 post / update / delete 기능을 수행.
5) 일치하지 않는다면 에러메시지 ("접근 권한이 없습니다.")