[2024.05.21 TIL] 내일배움캠프 25일차 (인증, 인가, bcrypt, 사용자 인증 미들웨어, 중첩 SELECT)

My_Code·2024년 5월 25일
0

TIL

목록 보기
34/113
post-thumbnail

본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.


💻 TIL(Today I Learned)

📌 Today I Done

✏️ 인증 (Authentication)

  • 인증(Authentication)은 사용자가 인증된 사용자인지 검증하는 작업

  • 일반적으로 신분증 검사, 사이트의 로그인 기능에 해당함


✏️ 인가 (Authorization)

  • 인가(Authorization)는 이미 인증된 사용자가 특정 작업을 수행할 권한이 있는지 검증하는 작업

  • 로그인 된 사용자만 게시글을 작성할 수 있도록 검증하는 과정을 의미함


✏️ bycrypt 모듈

  • 일반적으로 사용자의 비밀번호를 데이터베이스에 저장할 때, 보안을 위해 비밀번호를 평문이 아닌 암호화 하여 저장함

  • bcrypt 모듈은 입력받은 데이터를 특정 암호화 알고리즘을 통해 암호화 및 검증을 도와줌

  • bcrypt 모듈단방향 암호화되어 원래의 비밀번호로 복구할 수 없음

  • 하지만 사용자가 입력한 비밀번호와 비교를 통해서 복호화와 같은 기능을 할 수 있음

  • bcrypt 모듈의 암호화 알고리즘을 사용자가 입력한 비밀번호에도 적용시켜서 저장된 암호화된 비밀번호와 비교하면 비밀번호 일치 여부를 확인할 수 있음


✏️ bcrypt 암호화

import bcrypt from 'bcrypt';

const password = 'Sparta'; // 사용자의 비밀번호
const saltRounds = 10; // salt를 얼마나 복잡하게 만들지 결정

// 'hashedPassword'는 암호화된 비밀번호 입니다.
const hashedPassword = await bcrypt.hash(password, saltRounds);

console.log(hashedPassword); 
//$2b$10$OOziCKNP/dH1jd.Wvc3JluZVm7H8WXR8oUmxUQ/cfdizQOLjCXoXa

✏️ bcrypt 복호화

import bcrypt from 'bcrypt';

const password = 'Sparta'; // 사용자가 입력한 비밀번호

// DB에서 가져온 암호화된 비밀번호
const hashed = '$2b$10$OOziCKNP/dH1jd.Wvc3JluZVm7H8WXR8oUmxUQ/cfdizQOLjCXoXa'; 

// 'result'는 비밀번호가 일치하면 'true' 아니면 'false'
const result = await bcrypt.compare(password, hashed);

console.log(result); // true

// 비밀번호가 일치하지 않다면, 'false'
const failedResult = await bcrypt.compare('FailedPassword', hashed);

console.log(failedResult); // false

✏️ 사용자 인증 미들웨어

  • 사용자 인증 미들웨어는 클라이언트로부터 전달받은 쿠키를 검증하는 작업

  • 클라이언트가 제공한 쿠키에 담겨있는 JWT를 이용해 사용자를 조회

  • 사용자 인증 미들웨어 비즈니스 로직

    • 클라이언트로부터 쿠키를 전달 받음
    • 쿠키가 Bearer 토큰 형식인지 확인
    • 서버에서 발급한 JWT가 맞는지 검증
    • JWT의 userId를 이용해 사용자를 조회
    • req.user에 조회된 사용자 정보 할당
    • next()로 다음 미들웨어 실행
  • 위 로직의 사용자 인증 미들웨어인증 기능만 제공하고 있음

  • 만약 이후에 관리자 권한이나 등급별 권한이 필요하다면 별도의 인가 과정이 추가되어야 함

✏️ 사용자 정보 조회 API

  • 사용자 정보 조회 API 비즈니스 로직

    • 클라이언트가 로그인된 사용자인지 검증(인증 과정)
    • 사용자를 조회할 때, 1:1 관계를 맺고 있는 Users와 UserInfos 테이블을 조회
    • 조회한 사용자의 상세 정보를 클라이언트에게 반환
  • 단순히 Users 테이블 하나만 조회하는 것이 나닌, UserInfos 테이블도 함께 조회함

  • 그래서 각각의 테이블을 1번씩, 총 2번의 조회를 하는 것이 아니라 Prisma에서 제공하는 중첩 SELECT 문법을 사용

// 사용자 정보 조회 API
router.get('/users', authMiddleware, async (req, res, next) => {
    const { userId } = req.user;

    // userId를 가지고 1:1 관계를 맺고 있는 사용자 테이블과 사용자 정보 테이블을 동시에 조회
    const user = await prisma.users.findFirst({
        where: { userId: +userId },
        select: {
            userId: true,
            email: true,
            createdAt: true,
            updatedAt: true,
            // 중첩 select 사용
            UserInfo: {
                // 중첩 select는 SQL의 join문법과 동일한 역할을 함
                select: {
                    name: true,
                    age: true,
                    gender: true,
                    profileImage: true,
                },
            },
        },
    });

    return res.status(200).json({ data: user });
});

✏️ 중첩 SELECT

  • 중첩 SELECT 문법SELECT 내에 또다른 SELECT가 존재하는 것을 의미

  • 중첩 SELECT는 SQL의 JOIN과 동일한 역할을 수행함

  • 중첩 SELECT 문법을 사용하기 위해서는 Prisma model에서 @relation()과 같이 관계를 설정해야 함

  • @relation()으로 Prisma는 형재 모델에서 참조하는 외래키를 인식하고 SQL을 생성할수 있게 됨

  • 만약, 현재 테이블과 연관된 테이블의 모든 컬럼을 조회하고 싶다면, include 문법으로도 조회할 수 있음

중첩 select 문법과 include 문법에 대해 자세히 알아보고싶다면, 여기를 클릭하세요!



📌 Tomorrow's Goal

✏️ 노드 숙련 강의 시청하기

  • 2주차 남은 강의를 시청

  • 최대한 시청 후 과제 문서를 작성할 수 있도록 노력할 것!!

  • 내일도 시간이 많지 않기 때문에 오전, 오후에 최대한 시청할 예정



📌 Today's Goal I Done

✔️ 노드 숙련 강의 시청하기

  • 예비군으로 밀린 강의를 시청함

  • 원래는 2주차를 오늘 안에 다 시청하려고 했으나, 생각보다 내용이 어려웠음

  • 완전히 막힌다기 보다는 내용이 어려워서 검색하면서 이해하느라 진행이 느렸음

  • 현재 2주차 1/3 정도 완료한 상태

  • 주말을 이용해서 최대한 강의를 들을 예정


profile
조금씩 정리하자!!!

0개의 댓글