나만의 게시글 구현

김민재·2024년 9월 6일
0
post-custom-banner

1. 회원가입


1.body에서 데이터들을 가져온다.

2.동일한 이메일을 가지고 있는 사람이 존재하는지 확인한다.

3.Users테이블에 사용자를 생성한다.

여기서 bcrypt는 암호화를 시켜주는 기능을 가진 모듈인데 이를 이용하여 비밀번호와 같은 중요 정보들을 암호화해주는 기능이다.

4.UsersInfos 테이블에 값을 추가한다.

2. Log-in

1번에서 한 것은 말 그대로 회원가입, 즉 정보를 등록하기만 했을 뿐이다.

1.email로 사용자의 유무를 확인

  1. 전달 받은 password를 DB에 저장된 password와 비교한다.
    이때 bcrypt의 기능중에 하나인 compare을 사용하는데

    여기서 사소한 오타 하나로 오류가 뜬 적이 있어서 이런 문장을 비교할 때는 꼭 오류를 조심하도록 하자!

3.해당 userId를 토큰화하여 res(응답)에 쿠키를 실어서 돌려준다.

이후로부터는 해당 홈페이지에 접속중에는 계속 쿠키를 가지고 있게 된다.
이렇게 쿠키를 가진걸 이용하여 해당 쿠키로 인증이나 조회등에 이용할 수 있다.

3.사용자 인증 미들웨어 구현

우리는 쿠키를 통해서 인증을 처리할 수 있는데 해당 쿠키를 가지고 있다면 사용자가 인증이 되어서 권한을 행사할 수 있게되는 것이고, 해당 쿠키가 없거나 시간이 지나서 만료되어서 사라졌을 경우 권한을 행사할 수 없기 때문에 이를 미들웨어로 구현하여 넘어가기전에 조건을 확인할려고 한다.

import jwt from "jsonwebtoken";
import { prisma} from "../utils/prisma/index.js";

export default async function (req, res, next) {
  try {
    const { authorization } = req.cookies;
    if (!authorization)
      throw new Error("요청한 사용자의 토큰이 존재하지 않습니다.");

    //authorization "Bearer esasdasfas" 를 각각 tokentype과 token으로 나눔
    const [tokentype, token] = authorization.split(" ");

    if (tokentype != "Bearer")
      throw new Error("토큰 타입이 Bearer 형식이 아닙니다.");

    const decodedToken = jwt.verify(token, 'custom-secret-key'); // 실패시 error가 발생한다.
    const userId = decodedToken.userId;

    const user =await prisma.users.findFirst({
        where: {userId: +userId}
    })

    if(!user) throw new Error('토큰 사용자가 존재하지 않습니다.');

    req.user = user;
    next();
  } 
  catch (error) {
    if(error.name === "TokenExpiredError")
        return res.status(401).json({message: "토큰이 만료되었습니다."});
    if(error.name === "JsonWebTokenError")
        return res.status(401).json({message: "토큰이 조작되었습니다"});

    return res.status(400).json({message: error});
  }
}

이런식으로 구현한 authMiddlewares코드는 각종 router 코드에서 import하여 인증이 되었는지 되지않았는지를 확인하는 척도가 된다.

4. 사용자 조회

위의 미들웨어를 이용하여 검증을 하고 난 후, userId로 비교하여 해당 사용자의 정보를 조회한다.

여기서 적혀있지만 schema.prisma의 Users안에 usersInfos를 넣어두었기때문에 해당 select내에서 한번더 불러서 중첩 select문이 가능해진다.

도중에 좀 어려웠던 점은 schema작성시에 String과 string Int와 int DateTime과 datetime/ dateTime 등등 소문자도 지원하겠지? 라고 생각한 순간 내 착각이었다...

이후에도 bcrypt를 사용할 때 전달받은 password와 비교하는 password가 동일함에도 불구하고 도무지 정보를 제대로 받지 못할 떄가 있어서 여러모로 찾아봤었는데 결론이 사소한 오타긴 했지만 DB에서 해당 password를 저장하는 크기가 만약 bcrypt를 통해서 암호화한 값을 다 담지 못하는 경우에 짤려서 날라가버리는 경우가 있다고 하니 혹시나 이런오류가 발생했을때 크기도 확인하면.. 좋지않을까나?..

profile
ㅇㅇ
post-custom-banner

0개의 댓글