웹사이트 검색

Express.js에서 JSON 웹 토큰(JWT)을 사용하는 방법


소개

JSON 웹 토큰(JWT)은 인증 및 정보 교환을 지원합니다.

한 가지 일반적인 사용 사례는 클라이언트가 로그인 후 세션 정보를 보존하도록 허용하는 것입니다. 세션 정보를 로컬에 저장하고 요청 시 인증을 위해 서버에 전달함으로써 서버는 클라이언트가 등록된 사용자임을 신뢰할 수 있습니다.

경고: JWT를 localStorage에 저장하는 보안 위험에 유의하십시오.

이 기사에서는 Node.js 및 바닐라 JavaScript를 사용하여 서버-클라이언트 관계에서 JWT를 적용하는 방법에 대해 알아봅니다.

전제 조건

이 문서를 따라 하려면 컴퓨터에 다음이 설치되어 있어야 합니다.

  • Node.js를 로컬에 설치했습니다. Node.js를 설치하고 로컬 개발 환경을 만드는 방법에 따라 수행할 수 있습니다.

1단계 — 토큰 생성

jsonwebtoken은 JSON 웹 토큰의 구현입니다.

터미널에서 다음 명령을 실행하여 JavaScript 프로젝트에 추가할 수 있습니다.

  1. npm install jsonwebtoken

다음과 같이 파일로 가져옵니다.

const jwt = require('jsonwebtoken');

토큰에 서명하려면 3가지 정보가 필요합니다.

  1. 토큰 비밀
  2. 토큰에서 해시할 데이터 조각
  3. 토큰 만료 시간

토큰 비밀은 데이터를 암호화하고 해독하는 데 사용되는 긴 임의의 문자열입니다.

이 비밀을 생성하기 위한 한 가지 옵션은 다음과 같이 Node.js의 내장 crypto 라이브러리를 사용하는 것입니다.

> require('crypto').randomBytes(64).toString('hex')
// '09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710a4da095a2ce285b009f0c3730cd9b8e1af3eb84df6611'

경고: 조심하세요! 비밀이 단순하면 인증되지 않은 침입자가 토큰 확인 프로세스를 훨씬 쉽게 깨뜨릴 수 있습니다.

이제 이 비밀을 프로젝트의 .env 파일에 저장합니다.

TOKEN_SECRET=09f26e402586e2faa8da4c98a35f1b20d6b033c60...

이 토큰을 Node.js 파일로 가져오고 사용하려면 dotenv를 사용해야 합니다.

  1. npm install dotenv

다음과 같이 파일로 가져옵니다.

const dotenv = require('dotenv');

// get config vars
dotenv.config();

// access config var
process.env.TOKEN_SECRET;

토큰에서 해시하는 데이터 조각은 사용자 ID나 사용자 이름 또는 훨씬 더 복잡한 개체일 수 있습니다. 두 경우 모두 특정 사용자의 식별자여야 합니다.

토큰 만료 시간은 1800초(30분)와 같이 토큰이 유효하지 않게 될 때까지의 시간을 자세히 설명하는 문자열입니다.

다음은 토큰 서명 기능의 예입니다.

function generateAccessToken(username) {
  return jwt.sign(username, process.env.TOKEN_SECRET, { expiresIn: '1800s' });
}

사용자 로그인 또는 로그인 요청에서 다시 보낼 수 있습니다.

app.post('/api/createNewUser', (req, res) => {
  // ...

  const token = generateAccessToken({ username: req.body.username });
  res.json(token);

  // ...
});

이 예는 req(request)에서 username 값을 가져옵니다. 그리고 토큰을 res(response)로 제공합니다.

이것으로 jsonwebtoken, cryptodotenv를 사용하여 JWT를 생성하는 방법을 마칩니다.

2단계 — 토큰 인증

Express.js 애플리케이션에서 JWT 인증 시스템을 구현하는 방법에는 여러 가지가 있습니다.

한 가지 접근 방식은 Express.js의 미들웨어 기능을 활용하는 것입니다.

작동 방식은 특정 경로에 대한 요청이 있을 때 (req, res) 변수를 app.get(( req, res) => {}).

미들웨어는 (req, res, next)의 매개변수를 취하는 함수입니다.

  • req는 전송된 요청(GET, POST, DELETE, PUT 등)입니다.
  • res는 다양한 방법으로 사용자에게 다시 보낼 수 있는 응답입니다(res.sendStatus(200), res.json( ) 등).
  • next는 미들웨어를 지나 실제 app.get 서버 응답으로 실행을 이동하기 위해 호출할 수 있는 함수입니다.

다음은 인증을 위한 미들웨어 기능의 예입니다.

const jwt = require('jsonwebtoken');

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization']
  const token = authHeader && authHeader.split(' ')[1]

  if (token == null) return res.sendStatus(401)

  jwt.verify(token, process.env.TOKEN_SECRET as string, (err: any, user: any) => {
    console.log(err)

    if (err) return res.sendStatus(403)

    req.user = user

    next()
  })
}

이 미들웨어 기능을 사용하는 예제 요청은 다음과 유사합니다.

GET https://example.com:4000/api/userOrders
Authorization: Bearer JWT_ACCESS_TOKEN

그리고 해당 미들웨어를 사용하는 요청의 예는 다음과 같습니다.

app.get('/api/userOrders', authenticateToken, (req, res) => {
  // executes after authenticateToken
  // ...
})

이 코드는 클라이언트가 제공한 토큰을 인증합니다. 유효하면 요청을 진행할 수 있습니다. 유효하지 않은 경우 오류로 처리될 수 있습니다.

3단계 - 클라이언트측 토큰 처리

클라이언트가 토큰을 받으면 향후 요청에서 사용자 정보를 수집하기 위해 토큰을 저장하려는 경우가 많습니다.

인증 토큰을 저장하는 가장 일반적인 방법은 HttpOnly 쿠키입니다.

다음은 클라이언트 측 JavaScript 코드를 사용하여 쿠키를 저장하기 위한 구현입니다.

// get token from fetch request
const token = await res.json();

// set token in cookie
document.cookie = `token=${token}`

이 접근 방식은 서버에 대한 향후 요청에 대해 참조할 수 있는 응답을 로컬로 저장합니다.

이것으로 토큰 요청, 토큰 생성, 토큰 수신, 새 요청과 함께 토큰 전달 및 토큰 확인의 흐름이 끝납니다.

결론

이 기사에서는 JWT와 이를 Node.js 애플리케이션에 적용하는 한 가지 접근 방식을 소개했습니다. 이 접근 방식은 jsonwebtoken, crypto, dotenvexpress의 조합에 의존했습니다.

JWT를 사용하는 또 다른 접근 방식은 JSON 웹 토큰 및 여권으로 API 인증을 구현하는 방법입니다.

JWT에 대한 자세한 배경 정보는 "Introduction\ 문서를 참조하세요.

Node.js에 대해 자세히 알아보려면 Node.js 주제 페이지에서 실습 및 프로그래밍 프로젝트를 확인하세요.