5 min to read
[항해 99] 프리즈마 정리
일단 yarn init으로 프로젝트 생성. 그리고 생기는 패키지에 type: module 넣기. scripts: { dev: nodemon src/app.js }입력하기 이러면 es6를 쓸 수 있고 yarn dev로 실행 가능.
그 후 설치를 yarn add prisma express nodemon dotenv joi @prisma/client jsonwebtoken winston cookie-parser 하기.
npx primsa init으로 프리즈마 프로젝트 시작. 프리즈마 폴더에 들어가서 model 이름. 이렇게 테이블을 만든다 . 여기서 자주 까먹는 거는 @default(autoincrement()). 데이터 타임은 타입이 DateTime @default(now()).
틀린거 정리
- 프리즈마 스키마 파일은 ““가 자동으로 안닫힌다 확인하자.
- String, Int, DateTime 헷갈리지 말기.
- createdAt은 @default(now()) updatedAt은 @updatedAt.
- 관계설정할때 @relation(fields:[], references:[], onDelete:Cascade). 이렇게 s가 뒤에 붙는걸 확인.
모델 연결
부모테이블에 연결 이름 자식테이블이름[]. 자식테이블에 연결이름 @relation(field:[이 테이블이름], reference: [부모테이블꺼], ondelete: Cascade).
일대일이라면 부모테이블에 연결이름 자식테이블이름? 자식테이블에 가서 똑같이 @relation 하기. env 파일 가서 제대로 s3의 주소가 제대로 되어있는지 확인하기. 데이터베이스이름//아이디: 비밀번호:rds엔드포인트:포트/사용할이름/옵션. 이렇게 작성한 뒤 npx prisma db push 그리고 여기에 비행기 나오면 성공한거.
그리고 이제 여기에 있는 모델을 연결하기 위해 index파일을 만든다. util 폴더를 만들어 여기 안에 prisma 폴더를 만들어 index 파일을 만든다.
이렇게 push해서 적용하면 프리즈마 클라이언트파일로 넘어가서 import {PrismaClient} from @prisma/client export const prisma = new PrismaClient({ log: [‘query’, ‘info’, ‘warn’, ‘error’], errorFormat: ‘pretty’,}) 이렇게 내보내고 라우터에서 가져온다.
이러면 프리즈마.이름 으로 쓸 수 있다.
SyntaxError: Named export ‘PrismaClient’ not found 그냥 한번더 yarn add @prisma/client 를 하자.
app.js
일단 express을 가져오고 app를 express의 객체로 가지고 온다.
import express from 'express'
import cookieParser from 'cookie-parser'
import route from './routes/index.js'
import logMiddleware from "./middlewares/logMiddleware.js";
이렇게 가져온 다음에 app = express()를 사용해 선언하기
그 이후 사용하겠다는 app.use를 사용한다
app.use(express.json())
app.use(cookieParser())
app.use(express.urlencoded({extended: false}))
app.use(logMiddleware)
app.use("/api", route) -> 이 라우터로 보낸다
index.js
라우트 폴더의 인덱스 파일에 가서 이게 라우터라고 선언을 해주자. import express from “express” router = express.Router()
그리고 이 라우터에서 이어지는 경로로 다른 라우터를 쓰기 위해 router.use 사용.
미들웨어
- 로그 미들웨어 ```javascript
import winston from ‘winston’;
const logger = winston.createLogger({ level: ‘info’, // 로그 레벨을 ‘info’로 설정합니다. format: winston.format.json(), // 로그 포맷을 JSON 형식으로 설정합니다. transports: [ new winston.transports.Console(), // 로그를 콘솔에 출력합니다. ], });
export default function (req, res, next) { // 클라이언트의 요청이 시작된 시간을 기록합니다. const start = new Date().getTime();
// 응답이 완료되면 로그를 기록합니다.
res.on(‘finish’, () => {
const duration = new Date().getTime() - start;
logger.info(
Method: ${req.method}, URL: ${req.url}, Status: ${res.statusCode}, Duration: ${duration}ms
);
});
next(); }
2. 인증 미들웨어
먼저 들어온 값을 가지고 토큰을 만들어보자.
req.body에서 아이디와 비밀번호를 가져온다.
let{nickname, password} = req.body.
이제 이 두가지를 가지고 유효성 검사를 한 다음 모델에 검사를 한다.
const user = await prisma.User.findFirst({
where:{nickname: nickname}
})
가장 처음 나오는 걸 찾는다.
만약 값이 있다면 회원가입이 되어있다는 뜻이니까 넘어가고 값이 없다면 (!user)라면 return res.status(404).json({errormessage:""}).
이렇게 보내고 프론트랑 할때는 이 errormessage가 오면 회원가입 페이지로 리다이렉트 하기.
있다면 jwt.sign을 가지고 토큰에 저장한다.
```javascript
const token = jwt.sign(
{
nickname: nickname,
},
process.env.JWT_SECRET,
{ expiresIn: '60m' } // 토큰의 유효기간을 60분으로 설정
);
res.cookie('토큰이름', `Bearer ${token}`);
닉네임이라는 이름에 아까 들어온 nickname을 넣는다. 그리고 두번째에는 비밀키가 들어간다 . 비밀키는 .env파일에 저장.
이렇게 쿠키에 이름을 설정해 내보냄. 그 후 쿠키를 확인해서 로그인이 되었는지를 확인해보자!
미들웨어 폴더에 가서 authmiddleware.js를 만든다. 그리고 import jwt from ‘jsonwebtoken’;
export default async function (req, res, next) {
const {jwt쿠키이름} = req.cookies
//없으면 로그인이필요
if(!jwt토큰){
return res.status(400).json({errormessage:"로그인을 해주세요"})
const [tokenType, tokenValue] = jwt쿠키이름.split(' ');
//그리고 토큰 타입을 확인
if (tokenType !== 'Bearer') {
res.clearCookie(jwt쿠키이름);
return res.status(403).json({
errorMessage: '전달된 쿠키에서 오류가 발생하였습니다.',
});
}
//타입이 맞다면 이게 변조되지 않는 값인지 확인
const{nickname} = jwt.verify(tokenvalue, process.env.SECRETKEY)
//나온 닉네임을 프리즈마에서 찾고 없으면 변조된거니까 res.status(404)반환
//있다면 미들웨어사용시 공통된 값을 쓸 수 있게 res.local 사용
const user = await prisma.users.findUnique({
where: { userId: +userId },
});
res.locals.user = user;
next();
}
다음에 쓰고 싶을때는 라우터에서 get부분에 미들웨어 넣고 res.local에서 가져오기.
메서드
- findmany({select:{}, where:{}})
- FindUnique({select: {}, where:{}})
- .create({ data:{}}) //이름이 다르면 테이블이름: 지금 가져온 이름
- .update({data:{}, where:{}})
- delete({where:{}}) 앞에 await 프리즈마.모델
joi메서드
import Joi from ‘joi’; const schema = Joi.object({ name: Joi.String()/number().alphanum()/erequired })
리프래시 토큰
애초에 토큰을 두개 발급하낟 하나는 보통으로 짧게 만들고 하나는 그냥 막 10일 정도로 길게 만든다. 그리고 만약 하나가 시간이 끝나 ‘TokenExpiredError’에러가 나면 리프래스 토큰을 쿠키에서 찾고 이 쿠키에서 verify를 사용해 값을 가져오고 이 값을 사용해 다시여기서 jwt.sign을 사용해 다시 만든다.
일단 app.js에서 import하면 라우터든 미들웨어든 전부 중간에 들어간다 전부 쓸거면 거기에 쓰고 따로따로 라우터에만 쓸거면 라우터에 쓰가 joi는 각각의 라우터 .json은 app에 들어간다
Comments