분류 Nodejs

JSON 웹 토큰으로 Node.js 애플리케이션 보안

컨텐츠 정보

  • 조회 447 (작성일 )

본문

프론트 엔드와 백엔드가 분리 된 웹 애플리케이션을 빌드 할 때, 로그인 뒤에 배치하는 한 가지 방법은 JSONWebToken을 사용하는 것입니다. 2010 년 초에 처음 소개되었을 때 매우 인기가 있었던 개념입니다. 이 글에서는 JSON 웹 토큰 (JWT)의 정의, 작동 방식 및 Node.js 애플리케이션에 통합하는 방법에 대해 설명합니다. 


https://dev.to/_marcba/secure-your-node-js-application-with-json-web-token-4d4e 


간단히 말해서 JSON 웹 토큰 


"JSON 웹 토큰은 공식 웹 사이트를 인용하여 공개적으로 업계 표준 방식으로 양 당사자 간의 청구를 표현합니다." 즉, 서버는 클라이언트가 보낸 정보 (JSON 형식)가 수정되지 않았으며 해당 서버에서 효과적으로 발행했는지 여부를 확인할 수 있습니다.


토큰에는 무엇이 포함됩니까?

  • ? 헤더 : 토큰 종류 (JWT) 및 사용중인 서명 알고리즘 (예 : SHA256)에 대한 추가 정보가 들어 있습니다. 헤더 JSON이 Base64Url로 인코딩되고 있습니다.
  • ? 페이로드 : 양 당사자가 공유하고자하는 정보 (또는 "클레임")를 포함합니다. 여기에는 원하는 것이 포함될 수 있지만 기본적으로 JWT 토큰은 공유 비밀없이 해독 될 수 있기 때문에 민감한 데이터 (예 : 비밀번호)를 공유하는 것은 좋은 생각이 아닙니다. JWT는 데이터를 암호화 할 목표가 없습니다. 나는 개인적으로 사용자 ID, 역할, 발행 날짜 및 만료 날짜를 사용합니다. 페이로드 JSON은 헤더 JSON뿐만 아니라 Base64Url로 인코딩됩니다.
  • ? 서명 : 서명은 인코딩 된 헤더, 인코딩 된 페이로드, 비밀 (서버 만 알고 있음)을 포함하며 헤더에서 결정된 알고리즘에 의해 서명됩니다.

해싱 알고리즘이 SHA256이면 서명이 다음과 같이 생성됩니다.


HMACSHA256(
base64UrlEncode(header)
+ "."
+ base64UrlEncode(payload)
,secret)


결국 세 부분은 모두 "."으로 구분되어 연결됩니다.


<Header>.<Payload>.<Signature>

다음은 JWT의 예입니다.


eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZDM5YzI4MjdhZDgyMjBmMTJiMGZkMWIiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE1NjUyNzE4NzUsImV4cCI6MTU2NjQ4MTQ3NX0.NmcvfTBmUw1cdEI1cNRHzq6q5W0HmPELoh8rd_7EFAc


jwt.io로 가서 토큰을 붙여 넣으십시오. 포함 된 모든 정보가 표시됩니다 (서명 제외).


0pbphwsfchpx1rby96bp.png 


JWT 토큰은 어떻게 작동합니까? 


JWT는 암호화 된 데이터를 교환하기 위한 것이 아닙니다. 비밀번호와 같은 합리적인 정보를 포함해서는 안됩니다. JWT의 핵심은 토큰 확인에 있습니다. 변조 된 토큰을 확인하려고 하면 (사용자 ID가 교환 되었을 수 있음) 토큰이 거부됩니다.


왜? 내용이 더 이상 서명과 일치하지 않기 때문입니다. 따라서 서명을 해시하는 데 사용하는 비밀을 얻을 때를 제외하고는 다른 사람이 유효한 토큰을 만들 수 없습니다.


어떤 이유로 JWT 비밀이 해킹되는 경우 즉시 변경해야 합니다. 그때부터 이미 존재하는 모든 토큰은 유효하지 않습니다. 로그인 한 일부 사용자에게는 약간 성가신 일이지만 아무도 응용 프로그램에 유효한 토큰을 생성 할 수 없도록 할 수 있습니다.


서버에서 JWT 워크 플로우는 어떻게 생겼습니까? 


JWT Workflow Between Client And Server 


우리는 일반적으로 JWT에 대해 잘 알고 있으므로 클라이언트-서버 교환에서 어떻게 작동하는지 예를 살펴 보자.


  1. 첫 번째 움직임은 클라이언트를 만듭니다. 웹 프론트 엔드 애플리케이션, 모바일 애플리케이션 등이 될 수 있습니다. 기본적으로 백엔드 애플리케이션과 상호 작용을 시도하는 모든 것 (예 : REST API). 로그인 자격 증명을 서버로 보내 확인합니다.
  2. 서버는 로그인 요청을 받으면 먼저 사용자 이름 / 이메일 및 비밀번호가 데이터베이스에 저장된 정보와 일치하는지 확인합니다. 신임 정보가 올 바르면 이 사용자가 자신이 누구인지 서버에 해당합니다.
  3. 다음으로 JWT 토큰이 생성됩니다. 여기서 사용자를 식별하는 데 중요한 정보가 페이로드로 전달됩니다. 발행 날짜와 만료 날짜를 포함 시키는 것도 좋습니다. 따라서 세션은 지정한 시간보다 더 이상 유효하지 않습니다. 일주일은 좋은 시간 간격 인 것 같습니다. 어쨌든 사용자는 응용 프로그램을 로그 아웃 해야 합니다. 그러나 이것은 좀비 로그인 사용자를 피함으로써 보안을 강화합니다.
  4. 그런 다음 토큰은 로그인 시도에 대한 응답으로 클라이언트에 반환 됩니다. 그가 토큰을 받으면, 로그인이 성공했음을 의미합니다. 토큰은 클라이언트 측 로컬에 저장해야 합니다. 웹 애플리케이션의 localStore이거나 모바일 애플리케이션의 디바이스 변수에 있을 수 있습니다.
  5. 서버와의 모든 추가 통신을 위해 클라이언트는 각 요청에 인증 헤더를 추가합니다. 이것은 다음과 같습니다. 인증 : 무기명
  6. 보호 된 리소스에 대한 새로운 요청이 서버에 도착하면 가장 먼저 인증 헤더가 요청과 함께 전달되는지 확인해야 합니다. 이 경우 토큰이 체크 아웃 되는지 확인하려고 시도합니다. 유효한 토큰이 아닌 경우 (조작, 만료 등) 요청이 즉시 거부되어야 합니다.
  7. 그러나 토큰이 유효하면 서버에 대해 사용자가 여전히 자신이 말한 것으로 간주하고 요청 된 리소스를 클라이언트에 대한 응답으로 반환 할 수 있다고 가정하는 것이 안전합니다.

Node.js 애플리케이션의 JWT 


이 글에서는 Node.js에서 웹 서버가 어떻게 작동하는지 자세히 설명하지 않겠습니다. 그러나 JavaScript 서버 환경에서 JWT를 사용하는 방법을 보여 드리겠습니다. 예비


예비 


JWT로 작업하기 위해 편리한 jsonwebtoken 라이브러리를 사용할 수 있습니다. 다음과 같이 설치하십시오.


npm install jsonwebtoken


토큰 만들기 


클라이언트가 올바른 로그인 자격 증명을 제공했는지 확인한 코드 위치 (아마도 데이터베이스를 확인한 직후)에서 JSON 웹 토큰을 만들 수 있습니다.


const token = jwt.sign(<Your payload>, <Your JWT secret>, { expiresIn: <Expiration Time> })

실제 예에서 다음과 같이 보일 수 있습니다.


const jwt = require('jsonwebtoken')
const token = jwt.sign({ _id: user._id, admin: true }, process.env.JWT_SECRET, { expiresIn: '1 week' })

두 가지 사항에 유의하십시오.


  • dotenv에 익숙하지 않은 경우 process.env.JWT_SECRET은 JWT 비밀번호가 있는 위치입니다. 토큰을 코드에 일반 텍스트로 저장하는 것은 좋은 생각이 아닙니다. 따라서 (dotenv) [https://www.npmjs.com/package/dotenv]와 같은 도구를 사용하여 토큰을 찾는 것이 좋습니다. Git 리포지토리에 업로드 되지 않는 파일.
  • expiredIn 속성은 문자열 형식의 사람이 읽을 수있는 시간 표시 일 수 있습니다.-* '4 일'-* '7 시간'-* '2 주'-* '6 개월'-* 등

토큰 확인 


클라이언트는 인증 헤더를 다음과 같이 설정해야 합니다. Bearer :. 따라서 먼저 문자열에서 "Bearer :"부분을 제거해야 합니다.

const token = req.header('Authorization').replace('Bearer ', '')

(req.header ( 'Authorization')는 인증 헤더를 읽는 Express.js 방법입니다)


그런 다음 제공된 토큰을 다음과 같이 확인할 수 있습니다.

const jwt = require('jsonwebtoken')
try{
    const payload = jwt.verify(token, process.env.JWT_SECRET) 
    console.log(payload._id)
} catch(error) {
    console.error(error.message)
}


토큰이 유효하면 페이로드 변수에서 모든 페이로드 데이터에 액세스 할 수 있습니다. 토큰이 유효하지 않은 경우 JWT 라이브러리는 처리 할 수 있는 오류를 발생 시킵니다.


요약 


보시다시피 JWT를 사용하는 것은 그렇게 복잡하지 않습니다. 가장 중요한 점은 JWT가 데이터를 암호화하지 않으므로 합리적인 정보를 교환하는 데 사용하지 않는 것입니다.

JSON 웹 토큰은 누군가가 주장하는 정보가 실제로 진짜인지 여부를 확인하는 훌륭한 기술입니다. 즐거운 코딩 되세요!