Authentication(인증)
1. sesson & cookie
쿠키
- 클라이언트 컴퓨터에 저장되는 작은 데이터 조각
- 서버로부터 전송되어 클라이언트 웹 브라우저에 저장
- 텍스트 형식으로 주로 사용자 인증, 설정, 장바구니 등에 사용
세션
- 웹 서버 측에서 유지되는 상태 정보
- 사용자에 대한 고유한 세션ID를 통해 식별
- 서버 메모리 또는 데이터베이스에 저장할 수 있음
2. JWT(JSON Web Token)
- 웹 애플리케이션과 서비스 간에 정보를 안전하게 전달하기 위한 인증 및 권한 부여 매커니즘을 구현하는 데 사용되는 표준화된 방법 중 하나
- JSON 포멧을 사용하여 정보를 표현하고 서명 및 암호화를 통해 정보의 무결성을 보장
{ Header | Payload | Signature }
Header : 토큰 유형 및 서명 알고리즘과 같은 메타데이터가 포함
Payload: 토큰에 포함될 데이터가 들어있는 부분
Signature: 헤더, 페이로드 및 비밀 키를 사용하여 생성된 서명으로 토큰의 무결성을 검증하는 데 사용
3. bcyrpt
- 해시 함수를 사용하여 비밀번호를 안전하게 저장하는 데 사용되는 암호화 라이브러리
- 단방향 해시 함수로 한 번 해시된 값을 다시 원래 값으로 역추적하는 것이 불가능
- 솔트(salt): 해시에 고유한 솔트 값을 추가하여 보안성을 높임. 같은 비밀번호를 가진 사용자가 있더라도 서로 다른 해시값을 가짐
- 작업인자(Adaptive Work Factor): 매개변수를 조정하여 해시 작업의 복잡성을 조절. 암호 분석학적으로 안전한 해시 함수를 유지하면서도 암호화 작업에 필요한 시간을 조절할 수 있게 함
✔ 해시 함수
임의의 길이의 데이터를 받아서 고정된 길이의 고유한 값으로 변환하는 함수. 이러한 변환된 값은 해시 값 또는 해시 코드라고 함
- 동일한 입력에 대해 항상 동일한 해시 값을 생성
- 고정된 출력 길이를 생성
- 해시된 값을 통해 원본 값을 복구할 수 없음
문제
controller/auth.js 에서 login()를 bcyrpt를 적용하여 로그인 프로세스를 만들어보자.
문제
jwt.js를 참고하여 controller/auth.js에 토큰을 발행하고 login()에 로그인 완료되면 클라이언트에 토큰을 출력하는 프로세스를 만들어보자
4. jsonwebtoken
- 웹 애플리케이션에서 인증 및 정보 교환을 위한 토큰 기반의 인증 방식 중 하나
- Base64로 인코딩된 JSON 객체이며 사용자 정보 및 기타 데이터를 안전하게 전송하기 위해 사용
-header : JWT의 유형과 해싱 알고리즘이 포함
{
"alg": "HS256",
"typ": "JWT"
}
- Payload: 토큰에 담길 정보가 포함
{
id: 'apple',
isAdmin: false
}
- Signature : 헤더와 페이로드를 인코딩하고 비밀 키를 사용하여 서명된 문자열. 서명은 토큰이 변조되지 않았음을 확인하는 데 사용
sign()
jsonwebtoken.sign(payload, secretOrPravateKey, [options, callback])
payload: JWT에 포함될 페이로드 데이터
secretOrPravateKey: JWT 서명하기 위해 사용될 비밀 키 또는 개인 키
// router/auth.js
import express from "express";
import { body } from 'express-validator';
import * as authController from '../controller/auth.js';
import { validate } from "../middleware/validator.js";
const router = express.Router();
const validateSignup = [
body('username').trim().isLength({min: 3}).withMessage('최소 3자 이상 입력'),
body('password').trim().isLength({min: 4}).withMessage('최소 4자 이상 입력'),
body('email').trim().isEmail().withMessage('이메일 형식 확인'), validate
]
router.post('/signup', validateSignup, authController.signup);
router.post('/login', authController.login);
router.get('/me', authController.verify);
export default router;
// controller/auth.js
import * as authRepository from '../data/auth.js';
import bcrypt from 'bcrypt';
import jswonwebtoken from 'jsonwebtoken';
const secret = "abcd1234%^&*";
async function makeToken(id){
const token = jswonwebtoken.sign({
id: id,
isAdmin: false
}, secret, {expiresIn: '1h'})
return token;
}
// 회원가입
export async function signup(req, res, next){
const { username, password, name, email } = req.body;
const hashed =bcrypt.hashSync(password, 10);
const users = await authRepository.createUser(username, hashed, name, email);
if(users){
res.status(201).json(users);
}
}
//로그인
export async function login(req, res, next){
const { username, password } = req.body;
const user = await authRepository.login(username);
// const bcryptPW = bcrypt.hashSync(password, 10);
// const result = bcrypt.compareSync('abcd1234', bcryptPW);
if(user){
if(bcrypt.compareSync(password, user.password)){
res.status(201).header('Token', makeToken(username)).json(`${username} 로그인 완료`)
}
else{
res.status(404).json({ message: `${username} 님 아이디 또는 비밀번호를 확인해주세요` });
}
}
// else{
// res.status(404).json({ message: `${username} 님 아이디 또는 비밀번호를 확인해주세요` });
// }
}
//토큰이 있는지 여부, 로그인 흔적 확인
export async function verify(req, res, next){
const token = req.header['Token'];
if(token){
res.status(200).json(token);
}
}
// data/auth.js
let users = [
{
id: '1',
// userid: "apple",
username: "apple",
password: "$2b$10$TvIhNWYtvCNzOA0ZkmNg6.YU3EG49msPLzxphLYahMT63DVWRWZTe",
name: "김사과",
email: "apple@apple.com",
url: "https://www.logoyogo.com/web/wp-content/uploads/edd/2021/02/logoyogo-1-45.jpg"
},
{
id: '2',
// userid: "banana",
username: "banana",
password: "$2b$10$TvIhNWYtvCNzOA0ZkmNg6.YU3EG49msPLzxphLYahMT63DVWRWZTe",
name: "반하나",
email: "banana@banana.com",
url: "https://img.freepik.com/premium-vector/banana-cute-kawaii-style-fruit-character-vector-illustration_787461-1772.jpg"
}
]
export async function createUser(username, password, name, email){
const user ={
id: "10",
username,
password,
name,
email,
url: "https://www.logoyogo.com/web/wp-content/uploads/edd/2021/02/logoyogo-1-45.jpg"
}
users = [user, ...users]
return users;
}
export async function login(username){
return users.find((users) => users.username === username);
}
// app.js
import express from "express";
import morgan from "morgan";
import tweetsRouter from './router/tweets.js';
const app = express();
app.use(express.json());
app.use(morgan("dev"));
app.use('/tweets', tweetsRouter); // 미들웨어
app.use('/auth', authRouter); // 추가
app.use((req, res, next) => {
res.sendStatus(404);
});
app.listen(8080);
// Postman에 Post로 등록
// http://localhost:8080/auth/signup
// {
// "username":"orange",
// "password":"3333",
// "name":"오렌지",
// "email":"orange@orange.com"
// }
// http://localhost:8080/auth/login
// {
// "username":"orange",
// "password":"3333"
// }
// bcrypt.js
import * as bcrypt from "bcrypt";
// npm i bcrypt
const password = 'abcd1234';
const hashed = bcrypt.hashSync(password, 10);
console.log(`password: ${password}, hashed: ${hashed}`);
// abcd1234
// $2b$10$Hth/FWGGv4G/s9Me2X/32OwvnPg2NzgWBIozsbB7D62HXn2vNPKb6
const result = bcrypt.compareSync('abcd1234', hashed);
console.log(result);
// jwt.js
import jwt from 'jsonwebtoken';
const secret = 'abcdefg1234%^&*';
const token = jwt.sign(
{
id: 'apple',
isAdmin: false
},
secret,
{ expiresIn: 2 }
)
setTimeout(() => {
jwt.verify(token, secret, (error, decoded) => {
console.log(error, decoded);
});
}, 3000);
console.log(token);
🤍
ChatGPT에게 물어본 오늘의 공부 -
✔ JWT와 bcrypt 차이점
JWT(JSON Web Token)와 bcrypt는 웹 개발에서 사용되는 두 가지 다른 보안 기술입니다. 각각의 주요 특징과 차이점은 다음과 같습니다.
- 용도:
- JWT: 사용자의 인증 정보를 안전하게 전송하기 위한 토큰 기반의 인증 방식입니다. 주로 사용자의 인증 및 권한 부여에 사용됩니다.
- bcrypt: 비밀번호를 안전하게 저장하고 검증하기 위한 해시 함수입니다. 주로 사용자의 비밀번호를 안전하게 저장하는 데 사용됩니다.
- 동작 방식:
- JWT: 사용자의 인증 정보(클레임)를 JSON 형식으로 페이로드에 포함시킨 후, 이를 서명하여 토큰을 생성합니다. 클라이언트는 이 토큰을 서버에 전송하여 자격 증명을 제공하고, 서버는 이를 검증하여 사용자를 인증하고 권한을 부여합니다.
- bcrypt: 사용자가 제공한 비밀번호를 단방향 해시 함수를 사용하여 안전하게 저장합니다. 사용자가 로그인할 때, 입력된 비밀번호를 다시 해시하여 저장된 해시 값과 비교하여 인증을 수행합니다.
- 보안 수준:
- JWT: 토큰은 서명되어 있어 위변조가 어렵지만, 토큰이 유출되면 해당 토큰을 사용하여 접근할 수 있는 리소스에 대한 권한이 부여됩니다.
- bcrypt: 해시된 비밀번호는 원본 비밀번호를 복구할 수 없는 안전한 형태로 저장되므로, 데이터베이스가 노출되어도 사용자의 비밀번호가 노출되지 않습니다.
- 적용 분야:
- JWT: 웹 애플리케이션에서 사용자의 인증 및 권한 부여에 사용됩니다.
- bcrypt: 웹 애플리케이션에서 사용자의 비밀번호를 안전하게 저장하고 검증하는 데 사용됩니다.
요약하면, JWT는 인증 및 권한 부여에 사용되는 토큰 기반의 인증 방식이며, bcrypt는 사용자의 비밀번호를 안전하게 저장하고 검증하는 데 사용되는 해시 함수입니다. 두 기술은 각각 다른 목적과 동작 방식을 갖고 있으며, 보안 수준과 적용 분야에서도 차이가 있습니다.
✔ 토큰(Token)과 해시함수(Hash Function)의 차이점
토큰(Token)
1. 정의: 토큰은 주로 인증 및 권한 부여에 사용되는 보안 요소로, 사용자가 자격 증명을 증명하는 데 사용됩니다. 토큰은 사용자의 인증 정보를 포함하고 있으며, 일반적으로는 JSON 형식으로 구성되어 있습니다.
2. 종류:
- 액세스 토큰(Access Token): 주로 사용자가 서비스에 접근하거나 API를 호출할 때 사용되는 토큰입니다. 인증 후에 발급되며, 일정 기간 동안 유효합니다.
- 리프레시 토큰(Refresh Token): 액세스 토큰을 재발급받기 위한 토큰으로, 보통 인증에 사용되며 액세스 토큰의 만료 시간이 지난 경우에 사용됩니다.
3. 작동 방식:
- 사용자가 로그인하면, 서버는 유효한 자격 증명에 대한 토큰을 발급합니다.
- 클라이언트는 발급된 토큰을 저장하고, 이를 이용하여 서버에 인증 및 권한 요청을 합니다.
- 서버는 토큰을 검증하고, 유효한 경우 요청에 응답합니다.
해시 함수(Hash Function)
1. 정의: 해시 함수는 임의 크기의 데이터를 고정 크기의 고유한 값으로 변환하는 함수입니다. 해시 함수는 일방향 함수로서, 입력값을 해시 값으로 변환할 때는 가능하지만, 해시 값을 입력값으로 복구하는 것은 매우 어렵거나 불가능합니다.
2. 특징:
- 단방향성(One-way): 해시 함수는 입력값에서 해시 값을 생성하는데, 해시 값을 다시 입력값으로 역추적하는 것이 매우 어렵습니다.
- 고유성(Unique): 서로 다른 입력값에 대해 동일한 해시 값을 생성하는 일이 거의 없어야 합니다.
- 충돌 저항성(Collision Resistance): 서로 다른 입력값에 대해 동일한 해시 값을 생성하는 충돌이 발생할 확률을 최소화해야 합니다.
3. 활용:
- 비밀번호 저장: 사용자의 비밀번호를 안전하게 저장하기 위해 해시 함수를 사용합니다. 사용자의 비밀번호를 해시화하여 데이터베이스에 저장하므로, 해시 값이 노출되어도 원본 비밀번호를 알 수 없습니다.
- 데이터 무결성 검증: 데이터의 무결성을 확인하기 위해 해시 값을 사용합니다. 데이터의 해시 값을 생성하여 저장한 후, 이후에 데이터가 변경되었는지 확인할 때 사용됩니다.
토큰과 해시 함수는 각각 인증 및 권한 부여, 데이터 보안 등 다양한 분야에서 사용되며, 정보 보안 및 웹 개발에서 중요한 역할을 합니다.
✔ 해시 함수와 토큰의 형태
- 해시 함수(Hash Function):
- 해시 함수는 입력값을 받아서 일정한 길이의 고정된 해시 값으로 변환하는 함수입니다. 일반적으로 해시 함수는 바이트 시퀀스나 숫자 형식의 데이터를 입력으로 받아서 해시 값으로 출력합니다. 이 해시 값은 일반적으로 바이트 시퀀스이므로 16진수나 Base64와 같은 인코딩을 통해 표현됩니다. 예를 들어 SHA-256 해시 함수를 사용하여 "Hello, World!"라는 문자열을 해싱하면 다음과 같은 형태가 됩니다: 2ef7bde608ce5404e97d5f042f95f89f1c2328719d56dc2b3a22cd
- 토큰
- 토큰은 주로 JSON 형식으로 구성된 문자열입니다. 토큰은 일반적으로 헤더(Header), 페이로드(Payload), 서명(Signature)의 세 부분으로 구성됩니다. 이들은 점(.)으로 구분되어 표시됩니다. 예를 들어 JWT(JSON Web Token)는 다음과 같은 형태를 가집니다:
- xxxxx.yyyyy.zzzz
- 여기서 xxxxx, yyyyy, zzzzz는 각각 헤더, 페이로드, 서명을 나타내며, 이들은 Base64 인코딩된 문자열입니다.
export default router를 하는 이유는 해당 파일에서 정의된 라우터 객체를 외부에서 사용할 수 있도록 내보내기 위함입니다. 이를 통해 다른 파일에서 해당 라우터 객체를 가져와서 사용할 수 있습니다.
일반적으로 Express 애플리케이션은 여러 개의 라우터를 사용하여 요청을 처리하고, 이러한 라우터들은 별도의 파일로 분리되어 관리됩니다. 따라서 라우터 파일에서 정의된 라우터 객체를 외부에서 사용할 수 있어야 합니다.
export default router 구문은 이를 가능하게 합니다. 이 구문을 사용하여 해당 파일에서 정의된 라우터 객체를 다른 파일에서 import하여 사용할 수 있습니다. 이는 모듈화된 코드를 작성하고 유지보수하기 쉽도록 도와줍니다.
✔ bcrypt.hashSync() 함수
bcrypt.hashSync() 함수는 동기적으로 비밀번호를 해시화하는 데 사용됩니다. 해시화는 입력된 비밀번호를 암호화하여 보안성을 높이는 과정입니다. bcrypt.hashSync() 함수는 주어진 비밀번호를 해시화하고, 해시화된 결과를 반환합니다.
일반적으로 사용 방법은 다음과 같습니다:

위 코드에서 password는 해시화할 비밀번호를 나타내며, 10은 솔트(rounds)라고 불리는 값입니다. 솔트는 해시화 과정에서 추가적인 보안성을 제공하기 위해 사용되는 값으로, 높은 값일수록 해시화 과정이 더욱 복잡해지고 보안성이 높아집니다.
bcrypt.hashSync() 함수는 해시화된 비밀번호를 반환합니다. 이 해시화된 비밀번호는 데이터베이스에 저장되거나 인증 시에 사용될 수 있습니다.
이 함수는 동기적으로 작동하므로 호출 시 프로그램의 실행이 차단될 수 있습니다. 만약 비동기적으로 사용하고 싶다면 bcrypt.hash() 함수를 사용할 수 있습니다.
✔ HTTP 상태 코드 201
HTTP 상태 코드 201은 "Created"를 나타냅니다. 이 상태 코드는 클라이언트의 요청이 성공적으로 처리되었고, 새로운 리소스가 생성되었음을 나타냅니다. 주로 POST 요청에 대한 응답으로 사용됩니다.
클라이언트가 새로운 리소스를 생성하는 요청을 보내고, 서버가 이 요청을 성공적으로 처리하여 새로운 리소스가 생성되었다면, 서버는 HTTP 상태 코드 201을 반환합니다. 이는 클라이언트에게 새로운 리소스의 위치를 알려주고, 클라이언트는 이를 통해 새로 생성된 리소스에 접근할 수 있습니다.
예를 들어, 회원가입이나 새로운 데이터의 추가 등의 요청에 대한 응답으로 주로 사용됩니다.
compareSync는 bcrypt 라이브러리에서 제공하는 함수 중 하나로, 주어진 비밀번호와 해시된 비밀번호를 비교하는데 사용됩니다.
보통 사용자가 로그인할 때, 입력한 비밀번호를 해시화하여 데이터베이스에 저장된 해시된 비밀번호와 비교합니다. 이 때 사용되는 것이 compareSync 함수입니다.
compareSync 함수는 주어진 두 비밀번호가 일치하는지 여부를 반환합니다. 만약 비밀번호가 일치하면 true를 반환하고, 일치하지 않으면 false를 반환합니다.
예를 들어, 아래와 같이 사용될 수 있습니다:
위 예제에서 password는 사용자가 입력한 비밀번호이고, hashedPassword는 데이터베이스에 저장된 해시된 비밀번호입니다. compareSync 함수를 사용하여 두 비밀번호를 비교하고, 그 결과를 isPasswordMatch 변수에 저장합니다. 이렇게 저장된 변수를 통해 비밀번호가 일치하는지 여부를 확인할 수 있습니다.
✔ header() 함수 란?
header() 함수는 Express.js에서 HTTP 응답 헤더를 설정하는 메서드입니다.
여기서 res는 Express의 응답 객체를 나타내며, header() 메서드를 호출하여 HTTP 응답 헤더를 설정할 수 있습니다.
header() 함수는 두 개의 인자를 받습니다:
- 헤더 이름 (Header Name): 설정하려는 헤더의 이름을 문자열로 전달합니다.
- 헤더 값 (Header Value): 설정하려는 헤더의 값을 전달합니다.
위의 코드에서는 header() 함수를 사용하여 'Token'이라는 이름의 헤더를 설정하고 있습니다. 이 헤더는 클라이언트로부터 온 요청에 대한 응답으로 사용자의 토큰을 전달하기 위해 설정됩니다. 설정된 'Token' 헤더의 값은 makeToken(username) 함수를 호출하여 생성된 토큰입니다.
따라서 클라이언트는 이 토큰을 사용하여 사용자의 인증 및 권한 부여를 처리할 수 있습니다.
✔ === 연산자
===는 일치 연산자입니다. 이 연산자는 왼쪽 피연산자와 오른쪽 피연산자를 비교하고, 두 값이 정확하게 같은지 확인합니다.
여기서 "정확하게 같다"는 두 값의 데이터 형식과 값이 모두 같아야 한다는 것을 의미합니다. 만약 두 값이 정확하게 같다면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
예를 들어:
- 5 === 5는 true를 반환합니다. 두 값 모두 숫자이고, 값이 같기 때문입니다.
- 'hello' === 'hello'도 true를 반환합니다. 두 값 모두 문자열이고, 값이 같기 때문입니다.
- 5 === '5'는 false를 반환합니다. 하나는 숫자이고, 다른 하나는 문자열이기 때문에 데이터 형식이 다르기 때문입니다.
- true === true는 true를 반환합니다. 두 값 모두 불리언이고, 값이 같기 때문입니다.
이와 반대로, == 연산자는 동등 연산자로, 데이터 형식을 변환하여 비교합니다. 따라서 ===보다 엄격한 비교를 수행합니다. 일반적으로 JavaScript에서는 ===를 사용하는 것이 권장됩니다.
✔ HTTP 상태 코드 404
HTTP 상태 코드 404는 "Not Found"를 나타냅니다. 이는 서버가 요청된 리소스를 찾을 수 없음을 의미합니다. 클라이언트가 서버에게 요청한 URL에 해당하는 리소스를 찾을 수 없는 경우에 사용됩니다.
일반적으로 404 오류는 다음과 같은 상황에서 발생합니다:
- 요청한 URL에 대한 페이지나 리소스가 서버에 존재하지 않는 경우.
- 잘못된 URL을 요청한 경우.
- 요청한 리소스가 이전에 존재했지만 삭제되었거나 이동되었을 경우.
웹 브라우저에서는 404 오류가 발생하면 "페이지를 찾을 수 없음"과 같은 메시지가 표시됩니다. 개발자는 404 오류를 처리하여 사용자에게 적절한 오류 메시지나 대체 콘텐츠를 제공할 수 있습니다.
✔ Morgan
app.use(morgan("dev"))은 Express 애플리케이션에서 HTTP 요청에 대한 로깅을 처리하기 위해 사용되는 미들웨어인 Morgan을 설정하는 것을 의미합니다.
Morgan은 HTTP 요청에 대한 로깅을 쉽게 구현할 수 있도록 도와주는 미들웨어입니다. dev는 Morgan의 로깅 형식 중 하나이며, 개발 환경에서 가장 자주 사용되는 형식 중 하나입니다. 이 형식은 개발자에게 간결한 형태의 로그를 제공하며, 다음과 같은 정보를 포함합니다:
- HTTP 요청 메서드 (GET, POST, 등)
- 요청 URL
- HTTP 상태 코드
- 응답 시간
따라서 이 코드는 Express 애플리케이션에서 요청에 대한 로깅을 활성화하고, 개발 환경에서는 간결한 형태의 로그를 생성하여 개발 과정을 돕습니다. 이를 통해 개발자는 애플리케이션의 동작을 쉽게 디버깅하고, 요청에 대한 상세한 정보를 확인할 수 있습니다.
✔ 로깅(logging)
로깅(logging)은 소프트웨어 시스템의 동작 및 활동을 기록하는 프로세스를 의미합니다. 주요 목적은 애플리케이션의 실행 중에 발생하는 이벤트와 상태를 기록하여 나중에 분석하거나 디버그하는 데 사용하는 것입니다.
로깅은 소프트웨어 개발 및 운영에서 매우 중요한 역할을 합니다. 몇 가지 주요 이유는 다음과 같습니다:
- 디버깅: 애플리케이션에서 오류가 발생했을 때, 로그를 통해 오류 발생 시점의 상태와 정보를 파악하여 디버깅하는 데 도움을 줍니다.
- 모니터링: 운영 중인 애플리케이션의 상태와 성능을 실시간으로 모니터링하고 추적하는 데 사용됩니다.
- 추적: 애플리케이션의 활동을 추적하고 사용자의 행동 및 트랜잭션을 기록하여 보안 검사 및 분석에 사용될 수 있습니다.
- 성능 최적화: 로그를 통해 애플리케이션의 성능을 모니터링하고 병목 현상을 찾아내어 최적화하는 데 도움이 됩니다.
로깅은 다양한 형식과 수준으로 수행될 수 있으며, 대부분의 프로그래밍 언어와 프레임워크에서 지원됩니다. 보통 로그는 텍스트 파일, 데이터베이스, 콘솔 등에 저장됩니다. 로깅은 소프트웨어 개발 및 운영에서 중요한 부분이며, 안정적이고 효율적인 로깅 시스템은 애플리케이션의 안정성과 성능을 보장하는 데 도움이 됩니다.
✔ 미들웨어(middleware)
미들웨어(middleware)는 소프트웨어 시스템에서 클라이언트의 요청과 서버의 응답 사이에 위치하여 이들 간의 통신을 처리하는 소프트웨어 구성 요소입니다. Express.js와 같은 웹 프레임워크에서 주로 사용되며, 요청과 응답 객체에 대한 접근 및 제어를 중간에 끼워 넣어 특정 작업을 수행하거나 요청을 처리하는 데 사용됩니다.
미들웨어는 일련의 함수로 구성되어 있으며, 각각의 함수는 요청 객체(req), 응답 객체(res), 그리고 미들웨어 체인을 제어하기 위한 다음 미들웨어로 이동할 수 있는 함수(next)를 인자로 받습니다. 이러한 미들웨어 함수는 주로 다음과 같은 작업을 수행합니다:
- 요청 전처리: 요청이 라우팅되기 전에 요청 객체의 속성을 변경하거나 검증합니다.
- 응답 처리: 서버가 클라이언트에 응답을 보내기 전에 응답 객체의 속성을 변경하거나 응답을 가공합니다.
- 에러 처리: 예외나 오류가 발생했을 때 에러 처리 미들웨어를 사용하여 오류를 처리하고 클라이언트에 적절한 응답을 보냅니다.
- 라우팅: 요청을 특정 엔드포인트로 라우팅하고 해당 엔드포인트에 대한 처리를 수행합니다.
미들웨어는 Express.js에서 app.use() 메서드를 사용하여 등록되며, 순서에 따라 실행됩니다. 이러한 특성을 통해 미들웨어는 요청과 응답을 가로채어 처리하고, 애플리케이션의 동작을 조정하고 보강하는 데 사용됩니다.
✔ 전처리(preprocessing)
전처리(preprocessing)는 데이터나 자료를 사용하기 전에 사전에 처리하는 과정을 말합니다. 이는 데이터의 형식을 변경하거나 필요한 정보를 추출하고 검증하는 등의 작업을 포함할 수 있습니다.
웹 개발에서 전처리는 주로 클라이언트의 요청을 받아들이고 처리하기 전에 수행됩니다. 이러한 전처리는 다음과 같은 목적으로 수행될 수 있습니다:
- 데이터 유효성 검사: 클라이언트가 제출한 데이터가 유효한지 검사합니다. 예를 들어, 사용자가 폼을 제출할 때 입력된 값들이 필수 항목이 채워져 있는지, 형식이 올바른지 등을 검사할 수 있습니다.
- 데이터 가공: 클라이언트로부터 받은 데이터를 필요한 형식으로 가공합니다. 예를 들어, 데이터를 정규화하거나 특정 형식으로 변환할 수 있습니다.
- 보안 검사: 클라이언트로부터 받은 데이터를 검사하여 보안 위험을 탐지하고 방지합니다. 예를 들어, 입력된 데이터에 악의적인 스크립트나 SQL 삽입 등의 공격이 있는지 검사할 수 있습니다.
- 인증 및 권한 검사: 클라이언트의 요청이 유효한지 검증하고, 요청한 작업을 수행할 권한이 있는지 확인합니다. 예를 들어, 사용자가 특정 기능을 사용하려면 로그인한 상태여야 하고, 그 사용자가 해당 기능을 수행할 권한이 있는지 검사할 수 있습니다.
전처리 과정은 웹 애플리케이션의 안정성, 보안성 및 사용자 경험을 향상시키는 데 중요한 역할을 합니다. 데이터의 유효성을 검사하고 가공하여 응용 프로그램의 오류를 방지하고 보안을 강화하는 데 도움이 됩니다.
✔ setTimeout(() => {
jwt.verify(token, secret, (error, decoded) => {
console.log(error, decoded); })
}, 3000);
- setTimeout 함수:
- setTimeout 함수는 지정된 시간(밀리초)이 경과한 후에 콜백 함수를 실행하는 자바스크립트의 함수입니다.
- 첫 번째 매개변수로는 실행할 함수가 전달되고, 두 번째 매개변수로는 실행을 지연할 시간(밀리초)이 전달됩니다.
- setTimeout 함수는 비동기적으로 작동하며, 일정 시간이 지난 후에 콜백 함수를 호출합니다.
- jwt.verify 함수:
- jwt.verify 함수는 JSON Web Token(JWT)을 검증하는 메서드입니다.
- 첫 번째 매개변수로는 검증할 JWT 토큰이 전달되고, 두 번째 매개변수로는 토큰을 서명하는데 사용된 비밀 키가 전달됩니다.
- 세 번째 매개변수로는 콜백 함수가 전달되며, 검증 결과(에러와 해독된 토큰)를 받게 됩니다.
- error와 decoded:
- jwt.verify 콜백 함수의 첫 번째 매개변수인 error는 검증 과정에서 발생한 오류를 나타냅니다. 오류가 발생하지 않으면 null이 됩니다.
- jwt.verify 콜백 함수의 두 번째 매개변수인 decoded는 검증된 토큰의 해독된 내용을 나타냅니다. 이것은 서명된 토큰의 내용이 됩니다.
- setTimeout의 작동 방식:
- setTimeout 함수는 비동기적으로 작동하며, 전달된 시간이 경과한 후에 콜백 함수를 호출합니다.
- 위 코드에서는 setTimeout 함수를 사용하여 3초(3000밀리초)가 경과한 후에 jwt.verify 함수를 호출하고, 검증 결과를 콘솔에 출력합니다.
🤍