나만의 작은 도서관
[TIL] 240527 캠프 43일차: 유효성 검사 Joi패키지, 정규식, Prisma Client DB 2개 연결 본문
[TIL] 240527 캠프 43일차: 유효성 검사 Joi패키지, 정규식, Prisma Client DB 2개 연결
pledge24 2024. 5. 27. 21:41오늘 배운 내용
요청 헤더에 속성을 추가하면 다음 미들웨어에서 해당 속성을 사용할 수 있다.
express를 사용하다보면 미들웨어가 줄줄이 연결되어 있는 경우가 자주 있는데, 이 때 이전 미들웨어에서 계산한 결과값을 다음 미들웨어가 사용하고 싶은 경우가 발생하기도 한다. 이럴 때 이전 미들웨어에서 요청의 헤더 속성으로 지정해 저장을 하게 되면 다음 미들웨어부터 해당 속성으로 값에 접근이 가능하다.
// 인증 미들웨어(auth)
export default async function (req, res, next) {
// 토큰이 유효한지 테스트
.
.
.
// 토큰이 유효하다면, req.account에 사용자 정보를 저장합니다.
req.account = account;
next();
}
// 캐릭터 삭제(DELETE Method) API : 인증 미들웨어 사용
router.delete("/characters/:characterId", auth, async (req, res) => {
.
.
.
// 캐릭터가 존재하지 않거나, 본인 캐릭터가 아닌 캐릭터를 삭제하려는 경우,
// 해당 사실을 클라이언트에 전달합니다.
if (!character) {
return res
.status(404)
.json({ errorMessage: "존재하지 않는 캐릭터입니다." });
} else if (character.accountId !== req.account.accountId) {
return res
.status(403)
.json({
errorMessage: "본인 캐릭터가 아닌 캐릭터는 삭제 할 수 없습니다.",
});
}
.
.
.
});
정규식 사용법
정규식을 사용하면 짧은 코드로 유효성 검사를 할 수 있다. 하지만 모르고 보면 어려워보이기만 하고 이해가 되지 않아 한 번 알아보았다.
// 예시(이메일 주소 패턴)
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
// ^: 문자열의 시작, $: 문자열의 끝을 의미
// [a-zA-Z0-9._%+-]: a~z, A~Z, 0~9, 그리고 특수문자('.', '_', '%', '+', '-' 총 다섯 개)사용가능
// +: 한 개 이상 반복가능
// [a-zA-Z0-9.-]: a~z, A~Z, 0~9, 그리고 특수문자 '-' 사용가능
// +: 한 개 이상 반복가능
// [a-zA-Z]: a~z, A~Z 사용가능
// {2,} : 최소 길이 2개, 최대 길이 제한없음
유효성 검증 패키지 Joi 사용법
유효성 검증을 하는 데에 용이하게 사용할 수 있는 joi 패키지에 대해서 사용법을 한 번 더 알아보았다. joi에서는 정규식을 통한 유효성 검증 규칙을 넣을 수 있으며, 그 외에서도 min, max와 같이 최소/최대 문자열 길이를 제한할 수도 있다. 제작한 검증 규칙으로 검증하고 싶다면 joi.validate()함수를 이용하여 검증한다.
// 터미널에서 joi 패키지를 추가하는 명령어
yarn add joi
// 파일에서 추가한 joi패키지를 임포트
import Joi from "joi"
// 유효성 체크를 위한 스키마 생성.
const schema = Joi.object().keys({
id: Joi.string()
.pattern(new RegExp("^[a-z]+[0-9]+$"))
.min(3)
.max(20)
.required(),
password: Joi.string()
.min(6)
.required(),
});
// 유효성 검증(오류 발생시 error에 저장)
const {error} = schema.validate({ id: accountId, password: accountPassword })
Prisma DB 2개 같이 사용하는 법
Prisma에서는 @Prisma/client와 같이 하나의 client를 사용해야 할 것 같지만 client를 각 DB마다 만들어 준다면 두 client를 사용할 수 있으며, 즉 DB 2개를 같이 사용할 수 있다. 하지만 DB 2개를 같이 사용하려면 다음과 같은 절차가 필요하다.
- .prisma파일 1개 더 추가하기
- 각 .prisma파일에 output변수 설정하기
- .env파일에 있던 DB_URL 2개로 나눠서 연결하기
- db 연동하기
$ npx prisma db pull --schema ./prisma/test.prisma
- client 생성하기
$ npx prisma generate --schema ./prisma/test.prisma
자세한 절차와 내용은 다른 분이 자세히 정리해놨다.
https://velog.io/@nohsangwoo/prisma-%EC%97%AC%EB%9F%AC%EA%B0%9C%EC%9D%98-db-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0
오늘의 Trouble Shooting
Problem 1. Joi.validate()의 오류 시 반환 값 문제
joi패키지를 이용해서 유효성 검사를 하려했지만 잘못된 id와 password에도 계속해서 통과되는 문제가 발생했다. joi 패키지를 잘 사용하지 않았던지라 어디서 문제가 발생했는 지 알 수가 없었다...
// 시도한 코드 1
if(!schema.validate({ id: accountId, password: accountPassword })){
return res
.status(400)
.json({ message: "아이디 또는 비밀번호가 조건에 맞지 않습니다." });
}
// 시도한 코드 2
try{
schema.validate({ id: accountId, password: accountPassword })
}
catch(error){
return res
.status(400)
.json({ message: "아이디 또는 비밀번호가 조건에 맞지 않습니다." });
}
Solve. Joi.validate()는 오류 발생 시, 오류 속성이 추가되는 방식이다.
Joi.validate()는 boolean값을 반환하지도, 오류를 발생시키지도 않았기 때문에 위 두 방식으로 오류를 잡으려 해도 잡히지 않았던 것이다. Joi.validate()는 오류가 발생하면 error라는 속성이 추가되는 방식이므로, error 속성이 존재하는 지 if문으로 확인하면 되었다.
// 오류 발생 시 error가 존재하게 된다.
const {error} = schema.validate({ id: accountId, password: accountPassword });
if(error){
return res
.status(400)
.json({ message: "아이디 또는 비밀번호가 조건에 맞지 않습니다." });
}
Problem 2. Error [ERR_UNSUPPORTED_DIR_IMPORT]: .../prisma\userClient is not supported resolving ES modules imported from .../src\utils\prisma\prisma_userClient.js 오류 발생
DB를 하나만 쓰다가 2개를 사용하기 위해 설정을 하고 있는 도중 위와 같은 오류가 발생하면서 계속 연결이 되지 않았다.
Solve. @prisma/client와 달리 /client/index.js까지 입력
이 오류는 Prisma Client를 생성할 때 디렉토리에서 모듈을 직접 가져오려고 시도했기 때문에 발생하는 것이다. 즉, 경로의 문제였고, 경로를 제대로 설정해주면 정상적으로 각 DB에 연결이 된다.
// prisma_gameDataClient.js
// 이렇게 변경!
//import { PrismaClient } from '../../../prisma/gameDatasClient';
import { PrismaClient } from '../../../prisma/gameDatasClient/index.js';
export const prisma = new PrismaClient({
// Prisma를 이용해 데이터베이스를 접근할 때, SQL을 출력해줍니다.
log: ['query', 'info', 'warn', 'error'],
// 에러 메시지를 평문이 아닌, 개발자가 읽기 쉬운 형태로 출력해줍니다.
errorFormat: 'pretty',
}); // PrismaClient 인스턴스를 생성합니다.
오늘 한 일
- Node.js 과제 필수 요구사항 코드 최종 수정 및 마무리
- Node.js 과제 선택 요구사항: 아이템, 유저 데이터베이스 분리해서 각각 연결, 돈 벌기 API 제작
- 네트워크 계층 글 초안 작성
'Today I Learn' 카테고리의 다른 글
[TIL] 240529 캠프 45일차: prisma: @map 생략, createMany (0) | 2024.05.29 |
---|---|
[TIL] 240528 캠프 44일차: prisma: --schema 옵션, $transaction (0) | 2024.05.28 |
[TIL] 240524 캠프 40일차: jsonwebtoken 라이브러리의 sign() 함수 (0) | 2024.05.24 |
[TIL] 240523 캠프 39일차: 쿠키, 세션, JWT (0) | 2024.05.23 |
[TIL] 240522 캠프 38일차: Http Mehod중 PUT과 PATCH의 차이점 (0) | 2024.05.22 |