Bcrypt & JWT 실습_11.8

송철진·2022년 11월 8일
0
post-thumbnail

1. Bcrypt 실습

설치 : npm install bcrypt --save

비밀번호 암호화 (Async)

  1. bcrypt 모듈을 import한다
const bcrypt = require("bcrypt"); 
  1. 암호화 할 평문
const password = 'password';
  1. Cost Factor
const saltRounds = 12; 
  1. hash() method로 평문(첫번째 인자, password)를 Cost Factor(두번째 인자, saltRounds)로 암호화한다.
const makeHash = async (password, saltRounds) => {
    return await bcrypt.hash(password, saltRounds); 
}
  1. 암호화 결과 확인:
const main = async () => { 
    const hashedPassword = await makeHash(password, saltRounds); 
    console.log(hashedPassword);
}
main();
'password' 
👉 b'$2b$12$76taFAFPE9ydE0ZsuWkIZexWVjLBbTTHWc509/OLI5nM9d5r3fkRG'

Bcrypt 검증

  1. compare() method로 평문(첫번째 인자, password)과 암호화된 값(두번째 인자, hashedPassword)을 비교한다
const checkHash = async (password, hashedPassword) => {
    return await bcrypt.compare(password, hashedPassword) 
}
  1. 같으면 true, 다르면 false가 return된다
const main = async () => {
    const hashedPassword = await makeHash("password", 12);
    const result = await checkHash("password", hashedPassword);
    console.log(result);
};
main()

2. JWT 실습

설치 : npm install jsonwebtoken --save

JWT 발급 (HS256)

  1. jsonwebtoken 라이브러리 import
const jwt = require('jsonwebtoken'); 
  1. 실제로 전달할 내용인 Payload 정의
const payLoad = { foo: 'bar' };
  1. 실제로 Secret Key는 노출되면 안 되기 때문에 환경변수로 관리해 주어야 합니다.
const secretKey = 'mySecretKey'; 
  1. sign() method로 Payload(첫번째 인자)와 Secret Key(두번째 인자)를 사용해 option(세번째 인자)이 없으면 HS256 알고리즘으로 JWT를 발급한다
const jwtToken = jwt.sign(payLoad, secretKey); 
  1. 생성된 JWT 값
console.log(jwtToken)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE2NTA1NTYxMzZ9.YAMgUMLhiVUwkRTr2rpOrIyWN0cTGLxsxZBqLAaKWUU

JWT 인증

  1. verify() method로 JWT(첫번째 인자)를 Secret Key(두번째 인자)로 검증하여 JWT의 Payload를 확인한다
  • 토큰을 만들 때 사용한 Key가 아니면 에러가 발생한다.
const decoded = jwt.verify(jwtToken, secretKey); // (1)
  1. JWT를 디코드하여 확인된 Payload 값
console.log(decoded)

👉 { foo: 'bar', iat: 1650555667 }

JWT 구조 확인하기

3. 다른 엔드포인트에 인증 절차를 적용해보자

요약

  • Middleware : Express 서버의 라이프 사이클에서 요청과 응답 중간에서 목적에 맞게 기능을 처리하는 함수
  • 내장 Middleware뿐만 아니라 사용자가 Middleware를 직접 정의할 수 있다.
  • Middleware를 직접 정의 할 때는 request, response, next를 인자로 받아야 하며 next() 함수를 통해 다음 Middleware를 호출한다.
  • Token을 검증하는 Custom Middleware를 만들어 로그인을 한 사용자만 이용할 수 있는 함수를 실행하기 전에 인증 절차 진행할 수 있다.
  • Router에 token 검증 Middleware을 추가하여 Router Middleware → Token 검증 Middleware → Controller 순으로 코드를 진행 할 수 있다.

Middleware란?

Express 서버의 라이프 사이클에서 요청과 응답 중간에서 목적에 맞게 기능을 처리하는 함수.
Express.js는 내장 Middleware를 제공 하기도 하지만, 사용자가 원하는 특정 작업을 수행하게 할 수 있게 사용자가 직접 Middleware를 정의 할 수 있다.

Middleware를 직접 정의 할 때는 3개의 인자를 받아야 한다.

  1. req: HTTP request 객체
  2. res: HTTP response 객체
  3. next: 다음 middleware를 호출하는 함수

next() 함수를 통해 다음 middleware가 호출되어야 한다.

const myCustomMiddleware = async(req, res, next) => {
    ...
	
    next()
}

1. JWT를 검증하는 Middleware 만들기
/middlewares/auth.js 생성

// auth.js

const validateToken = async (req, res, next) => {
    try {
        const token = req.headers.authorization; // request의 headers에서 token 가져오기

	. . . // token 검증 코드 작성

	next(); // 검증 완료 후 다음 middleware 실행
    } catch (err) {
        next(err); 
    }
};

2. 기본 router의 2번째 인자에 Middleware를 추가한다
router를 통해 controller를 실행한다

const express = require("express");
const router = express.Router();
import { validateToken } from '../middlewares/auth'; // 추가
const { postController } = require("../controllers");

router.post("", validateToken, postController.createPost); // 2번째 인자 validateToken 추가

module.exports = router;
profile
검색하고 기록하며 학습하는 백엔드 개발자

0개의 댓글