Raw Query

원시 쿼리라고 불리며, Raw Query로 Node.js에서 데이터베이스에 SQL을 이용해 직접 쿼리를 요청할 수 있다.

  • 엄청나게 긴 쿼리를 수행하거나 트랜잭션을 직접적으로 관리하는 장점을 가지고 있다.


mysql2 라이브러리 설치

# yarn으로 프로젝트를 초기화합니다.
yarn init -y

# express와 mysql 드라이버를 설치합니다.
yarn add express mysql2

mysql2는 MySQl 데이터베이스를 Node.js에서 사용할 수 있게 도와주는 라이브러리, 데이터베이스 드라이버라는 이름으로 불림


Raw Query 사용법

mysql2 라이브러리에서 Raw Query는 connect.promise().query() 형식으로 사용합니다.

SHOW TABLES를 통해 테이블을 조회할 수 있습니다.


Raw Query의 단점

  • 엄청 많은 서비스와 연관되어 있는 경우 수정해야할 코드가 수백, 수천개가 되어버림

  • 사용자의 입력을 그대로 데이터베이스에 요청하기 때문에 SQL 인젝션에 취약함

** ORM을 통해 Node.js에서 SQL을 직접 작성하지 않고, Javascript 만으로 데이터베이스를 조작할 수 있게 되어 코드의 유지보수성이 증가해, 더욱 객체지향적인 프로그래밍이 가능함**



ORM과 Prisma

Prisma는 ORM(Object Relational Mapping)으로써 Javascript 객체(Object)와 데이터베이스 관계(Relation)를 연결(Mapping) 해주는 도구

  • Node.js환경에는 TypeORM, Prisma, Sequelize 등 다양한 ORM이 존재

  • Prisma는 여러가지 관계형 데이터베이스(RDB)를 사용할 수 있음.


ORM 장단점

장점

  • 프로덕션에서 사용하는 데이터베이스가 언제 바뀔지 알 수 없다

    • Raw Query코드를 전부 고치는 것은 힘들지만, ORM의 경우 속성값만 바꾸면 된다.
  • 데이터베이스에서 사용하는 DB 또는 Table 속성이 변경되었을 때 빠르게 수정이 가능


단점

  • 극한의 성능을 요하는 상황에서는 Raw Query가 더 좋다

  • 복잡한 쿼리를 작성할 때, ORM에 대해 깊이있게 알아야 한다.


Prisma 설치하기

# yarn 프로젝트를 초기화합니다.
yarn init -y

# express, prisma, @prisma/client 라이브러리를 설치합니다.
yarn add express prisma @prisma/client

# nodemon 라이브러리를 DevDependency로 설치합니다.
yarn add -D nodemon

# 설치한 prisma를 초기화 하여, prisma를 사용할 수 있는 구조를 생성합니다.
npx prisma init
  • prisma는 Prisma를 터미널에서 사용할 수 있도록 도구를 설치하는 패키지

    • ex) npx prisma init
  • @prisma/client는 Node.js에서 Prisma를 사용할 수 있게 해줌

  • nodemon은 개발 코드가 변경되었을 때 자동으로 서버 재시작을 해주는 패키지


  • npx prisma init을 통해 prisma 폴더 안에 prisma.schema 파일 생성

* prisma.schema파일은 Prisma가 사용할 데이터베이스를 설정하기 위한 파일이라 절대 지우지 말것

  • .env파일이 생성됨

* 이 파일은 외부에 공유되어선 안되는 비밀 정보들이 저장된 파일

  • .gitignore파일 생성

* .env 파일이 업로드 되지 않도록 설정되어 있음

여기서 생성된 폴더나 파일들을 절대로 임의로 옮기지 말것!


nodemon 라이브러리는?

파일을 저장할 때마다 변경 사항을 감지하고, 자동으로 서버를 재시작해주는 라이브러리

  • 매번 코드를 수정하거나 서버에서 에러가 발생해 종료되었을 때, 매번 서버를 재시작시켜야 하는 문제를 해결해줌


nodemon 명령어

// 프로젝트 내에 nodemon이 설치되어 있으면 앞에 npx를 붙여서 작성할 것
nodemon <실행할 JavaScript 파일명>

nodemon app.js


package.json에 nodemon을 이용해 서버를 실행하는 스크립트를 등록한다면, 매번 명령어를 입력하지 않아도 된다

// package.json

"scripts": {
    "dev": "nodemon app.js"
},

이제 터미널에서 yarn run dev 혹은 yarn dev명령어를 실행하면 nodemon을 이용해 서버를 시작할 수 있음


schema.prisma

Prisma가 사용할 데이터베이스의 설정 정보를 정의하기 위해 사용하는 파일

Prisma를 가장 처음 초기화 했을때, schema.prisma파일을 확인한다면, 2가지 구문이 작성된 것을 확인할 수 있다.

  • datasource

    • 데이터베이스를 정의하기 위해 사용

    • Prisma가 어떤 데이터베이스 엔진을 사용할 것인지, 데이터베이스 위치(URL)은 어디인지의 정보를 정의하는데 사용

  • generator

    • Prisma 클라이언트를 생성하는 방식을 설정하는 구문


datasource설정하기

// schema.prisma

datasource db {
  // MySQL 데이터베이스 엔진을 사용합니다.
  provider = "mysql"
  // 데이터베이스 연결 정보를 .env 파일의 DATABASE_URL 로부터 읽어옵니다.
  url      = env("DATABASE_URL")
}

url 부분에서 env("DATABASE_URL") 방식으로, 데이터베이스의 주소가 노출되지 않게 작성하는 dotenv 의 문법을 사용하고 있는데요.

env() 문법은 프로젝트의 root 폴더에 있는 .env 파일에 정의되어 있는 정보를 해당 schema.prisma 파일로 불러오는 것

여기서, dotenv는 어플리케이션의 환경 변수(Environment Variables)를 관리하는 모듈입니다.

실제 코드에서는 민감한 정보를 노출시키지 않도록 보호해주고, 개발 환경에 따라 다르게 설정해야 하는 값을 별도의 파일에서 관리할 수 있게 해줌


.env 파일 확인하기

# .env

DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

.env 파일은 key-value의 형태로 구성되어 있고, DATABASE_URL이라는 하나의 변수가 선언되어있는 것을 확인할 수 있다.


데이터베이스 URL

데이터베이스 URL은 Prisma가 어떤 데이터베이스와 어떻게 연결할지를 알려주는 중요한 정보

URL 내부에는 데이터베이스 엔진 유형, 사용자 아이디, 패스워드와 같은 정보가 포함

데이터베이스 URL은 크게 4가지로 나눠집니다.

  • Protocol

    • Prisma가 사용할 데이터베이스 엔진을 나타냅니다.

    • postgresql, sqllite, mysql과 같은 데이터베이스 엔진을 정의합니다.

  • Base URL

    • 데이터베이스의 엔드 포인트아이디, 패스워드, 포트 번호를 나타냅니다.

    • <Id>:<Password>@<RDS Endpoint>:<Port>의 형태로 구성됩니다.

  • Path

    • MySQL에서 사용할 데이터베이스 이름을 설정하는 구성 요소입니다.
  • Arguments

    • Prisma에서 데이터베이스 연결을 설정하는데 필요한 추가 옵션을 나타냅니다.

    • 데이터베이스와 연결할 수 있는 최대 커넥션 갯수, 타임아웃 시간 등이 있습니다.


Prisma model

Prisma의 model 구문은 특정 Table과 Column의 속성값을 입력하여, 데이터베이스와 Express 프로젝트를 연결 (Mapping)시켜줌

  • modle 구문은 Prisma를 사용할 때 가장 많이 작성하게 될 구문이며, Prisma가 사용할 데이터베이스의 테이블 구조를 정의하기 위해 사용

  • schema.prisma 파일에서는 model에 작성된 정보를 바탕으로 Prisma Client를 통해 JavaScript에서 MySQL의 테이블을 조작할 수 있게 됨

  • model 구문은 Javascript에서 MySQL의 테이블을 사용하기 위한 다리 역할을 수행하며, MySQL과 실제 연결되어 사용할 수 있게 도와 줌


상품 테이블 예시

// schema.prisma

model Products {
  productId   Int     @id @default(autoincrement()) @map("productId")  // @id는 Primary KEY 지정, @default(autoincrement())는 기본 값(1씩증가)
  productName String  @unique @map("productName")  // @map("productName")이 컬럼명이고 왼쪽에 있는 productName은 Node.js에서 쓰는 명
  price       Int     @default(1000) @map("price")  // @default(1000) 기본값으로 아무것도 입력하지 않았을때 1000으로 지정됨
  info        String? @map("info") @db.Text  // 데이터 유형 뒤 '?'는 NULL을 허용하는 컬럼, @db.Text를 이용해서 db내에서 text라는 타입을 별도로 가질 수 있음

  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updatedAt @map("updatedAt")  // @updatedAt 자동 현재시간 반영

  @@map("Products")  // @@map("Products")을 사용하지 않으면 테이블명의 대문자는 전부 소문자로 치환 됨
}


Prisma DB, Table 생성

# schema.prisma 파일에 설정된 모델을 바탕으로 MySQL에 정보를 업로드
npx prisma db push


여러가지 Prisma CLI

  • prisma db push

    • schema.prisma 파일에 정의된 설정값을 실제 데이터베이스에 반영(push)

    • 내부적으로 prisma generate가 실행

    • 데이터베이스 구조를 변경하거나 새로운 테이블을 생성할 수 있음

  • prisma init

    • Prisma를 사용하기 위한 초기 설정을 생성

    • 이 명령어를 실행하면 schema.prisma 파일과 같은 필요한 설정 파일들이 생성

  • prisma generate

    • Prisma Client를 생성하거나 업데이트

    • 대표적으로, schema.prisma 파일에 변경 사항이 생겼거나, 데이터베이스 구조가 변경되었을 때, 이 명령어를 사용해 Prisma Client를 최신 상태로 유지할 수 있음

  • prisma db pull

    • 현재 연결된 데이터베이스의 구조를 prisma.schema 파일로 가져옴(pull)

    • 데이터베이스에서 구조 변경이 발생했을 때, 이 명령어를 사용하면 Prisma Schema를 최신 상태로 유지할 수 있음

    • 이후 prisma generate 명령어를 사용해 변경 사항을 Prisma Client에 반영할 수 있음


Prisma Client

Prisma는 model을 generate하면, 해당 모델에 대한 정보가 node_modules폴더 내에 있는 Prisma Client에 전달됨

→ 이전에 사용한 prisma db push도 내부적으로 generate가 실행

Prisma Client는 Prisma Schema에 정의한 데이터베이스 모델(model)을 TypeScript 코드로 변환하여, 개발자가 데이터베이스와 상호작용할 수 있게 해줌

이러한 과정을 통해, 데이터베이스를 JavaScript에서 손쉽게 다룰 수 있게 되고, Prisma Schema와 동기화된 Prisma Client를 이용해 데이터베이스를 사용할 수 있게 되는 것입니다.



Prisma Method

Prisma는 mongoose와 동일하게, findMany(), findFirst(), findUnique() 등 다양한 메서드를 지원

mongoose를 사용했을 때는 Schema를 이용해 DB를 사용하였다면, Prisma에서는 Prisma Client를 이용해 MySQL의 데이터를 조작



쿠키와 세션

쿠키

  • 쿠키는 사용자가 웹사이트를 방문할 때마다 이전에 방문했던 정보를 기억하는 데이터 파일

  • 데이터를 여러 사이트에 공유할 수 있어 보안에 취약

  • 쿠키는 문자열 형식으로 존재, 쿠키간에는 세미콜론으로 구분


세션

  • 쿠키를 기반으로 구성된 기술

  • 쿠키와 다르게 세션은 데이터를 서버에만 저장

  • 보안성이 좋으나, 사용자가 많은 경우 서버에 많은 부하가 걸림



JWT

JWT는 웹 표준으로, 서버와 클라이언트 사이에서 정보를 안전하게 전송하기 위해 도움을 주는 웹 토큰

header.payload.signature의 형식으로 3가지 데이터를 포함한다.

  • Header: 헤더는 어떤 암호화를 사용했는지와, 토큰의 타입이 정의되어 있다.

  • Payload: 페이로드는 실제 전달하려는 데이터를 담고 있다.

  • Signature: 서명은 헤더와 페이로드, 그리고 비밀키를 이용해 생성됨, 이 서명은 토큰이 변조되지 않은 정상적인 토큰인지 확인할 수 있게 도와줌


JWT 특징

  • 비밀 키를 몰라도 복호화 가능

    • JWT를 가진 사람이라면 누구나 해당 토큰에 어떤 데이터가 있는지 확인 가능

    • 변조만 불가능 할 뿐

  • 민감한 정보(개인정보, 비밀번호 등)은 담지 말 것

  • JavaScript 이외에 다른 언어에서도 사용가능

    • JWT는 단순히 데이터 형식일 뿐


JWT 사용법

# yarn을 이용해 프로젝트를 초기화합니다.
yarn init -y

# jsonwebtoken, express 라이브러리를 설치합니다.
yarn add jsonwebtoken express


JWT를 써야하는 이유!

  • JWT가 인증 서버에서 발급되었는지 위변조 여부를 확인할 수 있음

  • 누구든지 JWT 내부에 들어있는 정보를 확인할 수 있음



인증, 인가

인증(Authentication)

인증(Authentication)은 서비스를 이용하려는 사용자가 인증된 신분을 가진 사람이 맞는지 검증하는 작업 (신분증 검사에 해당)

  • 인증은 일반적인 사이트의 로그인 기능에 해당

  • 로그인 기능은 일반적으로 id, password 조합으로 이루어짐


인가(Authorization)

인가(Authorization)는 이미 인증된 사용자가 특정 리소스에 접근하거나 특정 작업을 수행할 권한이 있는지를 검증 (놀이공원 자유이용권 확인에 해당)

  • 인증(로그인) 된 사용자가 게시글을 작성할 수 있는지 검증한다면, 이 과정을 인가 과정이라 부름



bcrypt

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

  • 개인정보보호법에서는 주민등록번호와 같은 정보는 암호화되어 저장되어야 함


bcrypt 모듈이란?

bcrypt 모듈은 입력받은 데이터를 특정 암호화 알고리즘을 이용하여 암호화 및 검증을 도와주는 모듈

  • 문자열을 단방향 암호화함

태그:

카테고리:

업데이트: