18/11/2023

heyjk2212·2023년 11월 18일

TodayILearned

목록 보기
3/8
post-thumbnail
  • 로그아웃 API는 인증된 사용자의 JWT 토큰을 삭제하는 방식으로 구혔했다. 즉 클라이언트에서 서버로 요청을 보내어 토큰을 삭제하도록 한다.

  • 클라이언트측의 쿠키에 저장된 JWT 토큰을 삭제한다.

  • JWT의 페이로드는 누구나 복호화하여 볼 수 있다.

  • JWT를 이용해서 쿠키에다가 데이터를 저장한다.

  • 토큰의 유효기간이 남아있는 경우에 보안에 취약해질 수 있다.

  • JWT는 헤더, 페이로드, 비밀키로 나뉜다.

  • 페이로드는 실제 전달하려는 데이터이다.

  • 비밀키: 서버에서 발급한 JWT가 맞는지 확인할 때 이 비밀키가 필요하다.

  • Bearer 토큰 형식으로 JWT를 보낸다.

  • 로그인 성공시 쿠키에 넣어서 보낼 JWT를 발급한다.
    쿠키를 발급하는 조건은 일반적으로 로그인 기능이다.

  • 사용자 인증 미들웨어: 쿠키확인해서 본인인증할때 필요함

  • jwt.verify(토큰, 비밀키) => 서버에서 발급한 토큰이 맞는지 확인할 때

  • TokenExpiredError: 토큰이 만료되었을 때 발생하는 에러

  • JsonWebTokenError: 토큰에 검증이 실패했을 때 발생하는 에어

  • 쿠키가 존재할 때 '사용자 인증 미들웨어'가 수행될 수 있다.

  • 만약에 쿠키인증에 실패했다면 해당하는 클라이언트의 쿠키를 삭제해줘야 한다.

  • res.clearCookie('authorization'): 특정 쿠키를 삭제시킨다

  • CICD: 무중단 배포

  • 쿠키/세션: 데이터를 교환하고 관리하는 방식

  • JWT: 단순히 데이터를 표현하는 방식

  • 쿠키를 이용해서 서버는 클라이언트에게 데이터를 전달시켜준다.

  • JWT는 쿠키에다가 데이터를 JWT로 바꿔서 사용할 수 있게 만들어준다.

  • JWT로 만든 데이터는 변조가 어렵고, (볼수는 있으나 수정이 불가능) 서버를 stateless(무상태)로 관리할 수 있다.

  • JWT는 JWT그 자체에서 데이터를 가지고 있기 때문에 서버에 별로의 상태 정보를 저장하지 않기 때문에 서버를 stateless로 관리할 수 있다.

  • bcrypt.hash(): 비밀번호 암호화. 비밀번호를 해시화 해서 저장할 수 있다. 해시화된 비밀번호를 다시 원본으로 역추적하는 것은 불가능하다(단반향 해시 함수를 사용)

  • 유저의 비밀번호나 주민등록번호와 같이 개인정보와 관련된 정보들은 데이터베이스에 저장할 때 암호화한 뒤에 저장을 해야하기 때문에 bcrypt 라이브러리를 사용했다.

  • bcrypt 라이브러리: 입력받은 데이터를 특정 암호화 알고리즘을 이용하여 특정한 문자열로 변환시킨다. 이 변환된 문자열은 단방향 암호화되어 원래의 비밀번호로 복구할 수 없다. 하지만 입력된 비밀번호가 암호화된 문자열과 일치하는지는 비교할 수 있다.

// bcrypt 암호화
import bcrypt from 'bcrypt'

const password = '나의비밀번호'
const saltRounds = 10 // 몇번 암호화를 할건지, 몇번 암호화를 반복해서 얼마나 복잡하기 만들지를 설정.

// 암호화된 비밀번호 만들기
const hashedPassword = await bcrypt.hash(password, saltRounds)

// bcrypt는 정보를 암호화하는데 시간이 많이 소요되기 때문에 await이라는 것을 통해서 비동기적으로 처리해줘야 한다.
// bcrypt 복호화
import bcrypt from 'bcrypt'

const password = '나의비밀번호' // 사용자가 입력한 비밀번호
const hashedPassword = '$2b$10$OOziCKNP/dH1jd.Wvc3JluZVm7H8WXR8oUmxUQ/cfdizQOLjCXoXa

// 'result'는 비밀번호가 일치하면 'true' 아니면 'false'
const result = await bcrypt.compare(password, hashed);

console.log(result); // true

// 비밀번호가 일치하지 않다면, 'false'
const failedResult = await bcrypt.compare('FailedPassword', hashed);

console.log(failedResult); // false'
  • Stateless: Node.js의 서버가 죽었다 살아나도 똑같은 동작을 하면 stateless(서버와 상관없이 사용가능)하다고 볼 수 있다.

  • stateful: 반대로 서버가 죽었다 살아났을 때 조금이라도 동작이 다른 경우 stateful하다(서버의 상태가 그대로 보존된다)고 볼 수 있다.

  • 쿠키와 세션은 사용자의 로그인 정보나 세션 데이터를 서버에 저장하므로 상태를 유지한다. 따라서 stateful(상태보존)하게 데이터가 관리된다.

  • JWT는 JWT내부에 데이터를 관리되고 있기 때문에, stateless, 즉 서버가 언제든지 죽었다 살아나더라도 JWT안에 있는 데이터는 변조되지 않고, 서버에서 처음발급한 그 상태 그대로 존재한다.

  • 로그인 정보를 서버에 저장하면 무조건 stateful(상태 보존)이라고 할 수 있다.

  • jsonwebtoken 라이브러리에서는 JWT를 만들기 위해서 sign이라고 하는 메서드를 사용한다.

  • sign메서드는 첫 번째 인자로 payload를, 두 번째 인자로 비밀키를 받아서 JWT를 생성한다

const token = jwt,sign( { loginId: user.loginId, } , "customized_secret_key" // 비밀키가 필요함

  • JWT가 변조되지는 않았는지 검증하기 위해 jsonwebtoken 라이브러리의 verify메서드를 사용한다.

jwt.verify(token, 'customized_secret_key')

  • 클라이언트는 로그인 후 모든 API 요청에 JWT를 포함하여 전송한다

  • 인가(Authorization)기능은 사용자 미들웨어를 통해서 구현된다.

  • dotenv 파일은 환경 변수를 설정하고 관리하기 위한 파일로, 비밀 키를 관리하는데 사용될 수 있다. 보안적으로 민감한 정보를 dotenv 파일에 저장하고, 해당 파일을 프로젝트의 버전 관리 시스템(git 등)에서 제외하는 것이 일반적인 방법이다.

  • 모든 소스코드들은 src 폴더안에 넣는다. 포괄적으로 소스코드 파일들을 src 폴더에 몰아넣음으로써 해당하는 소스파일과 관련된 정보랑, 소스파일 외적으로 관리되는 폴더를 구분한다. 최상단에 위치해 있는 폴더들이 어떤 역할을 가지고 어떤 책임을 가지는지 구분하기 위함이다.

  • 로그인 검증에 성공하면 JWT를 담고있는 쿠키를 생성하여 반환하게됩니다.

  • 클라이언트는 로그인 이후 요청부터 쿠키를 함께 보내면, 이를 통해 서버에서는 해당 사용자를 식별하고, 인증(Authentication), 인가(Authorization) 과정을 거칠 것 입니다

  • 사용자 인증 미들웨어를 통해서 로그인된 사용자인지 검증한다.

profile
She can do it, He can do it, Why not me?

0개의 댓글