Nodejs #07 JWT사용하기

수박·2020년 7월 12일
1

nodejs

목록 보기
7/19

세션과 쿠키라는 단어는 많이 들어보았으나 물어본다면 대답을 할 수 없었습니다. 이에 대해 정리해보려고합니다.


connectionless: HTTP는 클라이언트가 요청한 후 응답을 받으면 그 연결을 끊어버리는 특징이 있습니다.

연결을 끊는 순간 클라이언트-서버간 통신이 끝나고, 상태정보는 유지하지 않는 특성이 있습니다. 이를 stateless라 합니다.

쿠키와 세션은 이 두가지를 해결하기위해 사용합니다.


쿠키

  • 클라이언트(brower)로컬에 저장되는 키, 값이 들어있는 데이터 파일.
  • 사용자 인증이 유효한 시간을 명시, 유효시간이 정해지면 brower가 종료되어도 인증이 유지된다.
  • 클라이언트에 300개 저장가능, 도메인당 20개의 값만 가질 수 있다.
  • text형식으로 저장
  • 세션보다 속도 빠르나, 보안에는 좋지 않음

쿠키의 구성요소

  • 이름 : 쿠키를 구별하는데 사용하는 이름

  • 값 : 쿠키의 이름과 관련된 값

  • 유효시간 :쿠키의 유지시간

  • 도메인 : 쿠키를 전송할 도메인

  • 경로 : 쿠키를 전송할 요청 경로

쿠키의 동작방식

  1. 클라이언트가 페이지 요청
  2. 서버에서 쿠키생성
  3. HTTP헤더에 쿠키를 포함, 응답
  4. brower가 종료되도 쿠키 유지시간이 남아있다면 클라이언트에서 보관

사용 예시

  • 로그인 시 아이디와 비밀번호를 저장하는데 사용
  • 장바구니 기능
  • 자동로그인, 오늘 더 이상 이 창을 보지 않음.

세션

  • 세션은 쿠키를 기반, 서버측에서 관리
  • 서버에서 클라이언트를 구분하기 위해 세션 ID를 부여, brower가 서버에 접속해 brower를 종료할 때까지 인증상태를 유지
  • 일정 시간 응답이 없다면 정보가 유지되지 않게 설정 가능
  • 정보를 서버에 두어 쿠키보다 보안에 좋지만, 많아질 수록 서버메모리 많이 차지한다.
  • 동접자수가 많으면 성능저하의 요인
  • Object로 저장, 쿠키보다 느리나 보안에서는 좋다.
  • 화면이 이동해도 로그인이 풀리지 않고, 로그아웃 전까지 유지한다.
  • 누군가 어떤 사용자의 세션 아이디를 훔친다면 그 사용자처럼 로그인할 수 있게 됩니다. https를 이용해서 통신 하는 것이 좋고 cookie와 마찬가지로 session의 옵션으로 secure을 true로 주면 https에서만 세션 정보를 주고받을 수 있고 HttpOnly을 true를 주면 js를 통해서 세션 쿠키를 사용할 수 없도록 강제할 수 있습니다출처

세션의 동작방식

  1. 클라이언트가 서버에 접속시 세션ID발급받는다.
  2. 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장한다.
  3. 클라이언트에서 서버에 요청할 때, 이 쿠키의 세션 ID를 서버에 전달해 사용.
  4. 서버는 세션 ID를 전달 받아, 세션에 있는 클라이언트 정보를 가져온다
  5. 클라이언트에게 응답한다.

캐시와 다른점.

  • 캐시는 img, css, js등 brower, 서버 앞 단에 저장해놓고 사용.

세션은 서버 메모리를 많이 차지할 수 있기 때문에 이런 문제를 보완한 토큰기반인증방식, JWT(Json Web Token)을 많이 사용하는 추세.


JWT란?

참조글

Json포맷을 이용해 사용자에 대한 속성을 저장하는 WebToken.

사용자 정보를 JSON객체에 담아 암호화하고 해싱 작업을 거쳐서 문자열 토큰을 생성하는 기술.

클라이언트는 이 토큰을 HTTP Header에 추가하여 요청을 보냄으로써 사용자 인증을 얻게된다.

서버에 저장되지 않아 부하를 일으키지 않고 해싱을 통해 데이터무결성을 보장한다. (해싱 : 원문을 일정 길이의 byte로 변환)

토큰에 사용자 정보와 권한을 명시하는 것이다.

동작방식

  • JSON객체에 요구사항을 작성
  • '어떤' 암호화 방식으로 문자열 인코딩
  • HTTP Header에 추가해 사용자인증 요청
  • 서버에서 Header에 추가된 Token을 디코딩하여 사용자 인증

구조

JWT는 Header, Payload, Signature로 구성되어있다.

적절한 속성, 값을 명시하면 자동으로 라이브러리에서 인코딩, 해싱작업을 진행해줍니다.

헤더

typ, alg속성을 명시

  • typ : 토큰 타입 명시
  • alg : 해싱 알고리즘 명시
내용(payload)

토큰에 대한 정보를 작성

정보는 속성 + 값으로 표현되며, 이를 claim이라 한다.

클레임은 3가지로 작성할 수 있는데 registerd, public, private가 있다.

signature

헤더, 내용의 인코딩 값을 '.'으로 연결하여 합친 후 비밀키로 해싱. => 암호화작업

각 값을 합치면 JWT가 생성된다.


JWT는 HTTP Only옵션의 쿠키에 저장하는 것이 좋다.

쿠키에 저장하기 위해서는 cookie-parser라이브러리를 설치해서 사용할 수 있다.


JWT를 이용해서 토큰발행하기

jwt에서 웹토큰을 생성하기 위해선 sign()메소드를 이용한다.

생성될 토큰에 유저의 정보나 암호화를 위한 키 지정, 만료시간 등을담는 역할을 한다.

let token = jwt.sign({
              email : `${login_email}`
            },
            secretObj.secret, // 비밀키
            {
              expiresIn: '5m' // 유효시간
            })

쿠키에 유저정보가 저장된 토큰이 있다면, admin페이지에 요청할 때 해당 토큰의 계정명이 admin과 같은지 비교해야한다.

따라서 인코딩된 email의 값을 디코딩하여 root 또는 admin과 같은지 비교해야할 것이다.

토큰이 헤더에 어디에 담기는지부터 알아보아야겠다.

해당 페이지 헤더의 Cokkie에 잘 들어가있는 것을 확인했다.

그렇다면 이 쿠키의 내용을 다른 라우터에서도 유지되고, 가져올 수 있는지를 확인해야한다. => 다른 페이지에서도 잘 유지된다.

다른페이지에서 저장된 쿠키의 값을 가져오는 방법

=> route의 requset메소드인 cookies를 통해 가져올 수 있음.

let token = req.cookies['쿠키이름'];

이렇게 얻어진 인코딩된 토큰 내용을 다시 디코딩하여 원하는 계정명인지 확인해야하는 작업이 필요하다.

decode는 jwt의 메소드인 verity를 이용하면된다.

let decoded = jwt.verify(token, 비밀키);

이렇게하면 decoded는 인코딩하기전의 메일 내용으로 디코딩된다!


app.use

뜬금없지만.. 코드를 다시 보다가 정리가 잘된 글을 보고 작성..

app.use에 함수를 넣은 것을 middleware라고하고, route에 상관없이 request가 올 때마다 수행되는 내용이다.

위에서 순차적으로 실행되기 때문에 순서가 중요하다.

app.use에 들어가는 함수는 route의 함수와 동일하게 req, res, next 3개의 인수가 들어가고 함수 안에는 반드시 next()가 들어가야한다. 들어가지 않으면 다음 app.use함수를 실행시키지 못하고 그 안에서 계속 대기하게 된다.

쿠키, 세션설명 참고페이지

0개의 댓글