유튜브 클론 코딩을 하면서

mason.98·2022년 10월 12일
0

CS

목록 보기
3/3

- Node.js

브라우저안에서 실행되는 자바스크립트를 브라우저 밖에서도 사용할 수 있게 해준 런타임환경

  • JavaScript (자바스크립트)

    사용자와 상호작용하며 웹에 복잡한 기능을 구현할 수 있도록 도와주는 프로그래밍 언어이다.

  • 런타임 환경 (브라우저, Node.js)

    프로그래밍 언어가 구동되는 환경을 말한다.

- npm

많은 사용자가 배포한 Nodejs 패키지를 사용할 수 있게 도와주는 관리 도구
대표적인 예로 React.js, express.js가 있다.


- package.json

프로젝트에 대한 정보가 담겨 있다.

- scripts

실행할 명령어 단축키 npm run 단축키로 사용할 수 있다.

- dependencies

프로젝트/패키지를 실행하기 위해 필요한 패키지를 명시

- devDependencies

프로젝트/패키지를 개발하기 위해 필요한 패키지를 명시

- node_modules (폴더)

프로젝트에 필요한 패키지들의 실제 파일들


- Babel.js

최신 자바스크립트 문법을 Node.js에게 이해시켜주는 컴파일러 패키지

- Nodemon.js

npm i nodemon --save-dev

프로젝트 파일수정을 감지하여 서버를 재시작 시켜주는 패키지
사용하지 않는다면, 수정할 때마다 npm run dev 명령어를 입력해야 된다.


- Express.js

Nodejs 표준 웹 서버 프레임워크이다.

  • Controller(req, res)

    Nodejs안에서의 모든 함수는 컨트롤러이다.
    사용자의 요청(req)과 서버의 응답(res)을 처리한다.

  • Middleware(rea, res, next)

    사용자의 요청과 서버의 응답 사이에 위치한 컨트롤러이다.
    항상 next()를 반환한다.

  • morgan.js

    HTTP 요청(request)에 대한 정보를 담고 있는 로그 미들웨어 패키지

  • 라우터 - express.Router()

    라우터는 URL을 그룹별(users/videos)로 나누는 역할을 해준다.
    그룹별 라우터에서 컨트롤러를 호출한다.
    그룹별 라우터와 컨트롤러는 각각의 폴더(routes/, controllers/)로 관리한다.

    // 1. 라우터 미들웨어 등록 (server.js)
    	express.use("/", homeRouter)
    	express.use("/video", videoRouter)
    	express.use("/users", usersRouter)
    
    // 2. 그룹별 라우터 (routers/*)
    homeRouter, videoRouter, usersRouter = express.Router()
    
    // 2-1. 각 라우터의 컨트롤러 호출
    homeRouter.route("/login").get(getController).post(postController)
    videoRouter.route("/watch").get(getController).post(postController)
    usersRouter.route("/edit").get(getController).post(postController)
    
    // 3. 각 컨트롤러에서 res 반환 (controllers/*)
    const getController(req, res) => {
    	// GET 요청 처리 후 페이지 렌더링
    	res.render(...)
    }
    const postController(req, res) => {
    	// POST 요청 처리 후 페이지 렌더링
    	res.render(...)
    }
  • Form 데이터 파싱 미들웨어 (POST요청)

    브라우저에서 데이터를 입력/수정하고 express에게 form 데이터를 전송할 때 서버(express)가 이해할 수 있게 데이터를 자바스크립트로 변환해준다.
    기본값이 false 이므로 변경해주어야 한다.
    POST Controller에서 req.body.input name 로 받을 수 있다.

    //server.js (라우터 미들웨어보다 위에 입력해야 한다.)
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json());

- PUG

Express의 서버사이드 템플릿 엔진이다.
Html과 Javascript를 함께 작성하는데 도움을 주는 패키지이다.

  • 서버사이드 템플릿 엔진

    서버에서 가져온 데이터를 미리 정의된 템플릿에 넣고,
    html을 생성하여 사용자에게 응답(res)한다.
  • PUG 설정 (/src/views/*)

    // server.js
    app.set("view engine", "pug"); // PUG를 view engine으로 설정
    app.set("views", process.cwd() + "/src/views"); // PUG 파일 위치 설정
  • 장점 1 - 포함 (Include)

    파일들을 쪼개어 관리할 수 있다.

    // views/footer.pug
    footer TESTTEST
    
    // views/base.pug
    ...
    include footer <=== <footer>TESTTEST</footer>로 변환
  • 장점 2 - 상속 (extends, block)

    extends로 베이스 파일을 확장(extends)한다.
    block으로 베이스 파일에 데이터를 넣어준다.

    // views/layout.pug (베이스파일)
    title
    	block title // title 이름으로 block 설정
    body
    	block content // content 이름으로 block 설정
    
    // views/page.pug (베이스파일을 확장할 파일)
    extends layout.pug // 확장할 베이스파일 설정
    
    block title  // 해당 베이스파일 block에 데이터 넣기
    	page
    
    block content  // 해당 베이스파일 block에 데이터 넣기
    	contents
  • 장점 3 - mixins (데이터를 받아 가공한 다음 출력)

    서버에게 받은 데이터를 재사용하는 데에 도움을 준다.

    /* 위치: getController.js 
       - videos는  {title: "abc", content:"test" ...} 등의 정보를 갖고 있다. */
    res.render("home", videos)
    // home.pug
    include ../mixins/video // mixin Include
    
    each item in videos
    	+video(item) // mixin 이름 
    // /mixins/video.pug
    mixin video(video)
    	div
        	span video.title
    	    span video.content
        	...

    - MongoDB

    검색에 최적화 되어 있는 document-based 데이터베이스이다.

  • document-based: JSON과 같이 저장하고 조회할 수 있다.

  • mongoose (Express와 MongoDB의 연결다리 패키지)

    • 자바스크립트를 통해 MongoDB에 CRUD를 할 수 있다.
    • m1 기준 연결
      mongod --config /opt/homebrew/etc/mongod.conf --fork
    • 명령어 모음
  • bcrpyt

    간단한 단방향 암호화 해시 함수 패키지이다.
    단순히 입력하여 해시된 데이터가 같은지 다른지만 비교할 수 있다.


- express-session

브라우저-서버(express)간에 로그인/로그아웃 기능 구현을 도와줌
브라우저는 세션ID만, 서버(express)에는 세션 정보가 담겨있다.

  • 세션 동작 과정
  1. 브라우저에서 express(서버)에게 로그인 요청
  2. express(서버)에서 해당 유저의 세션 생성 후, 쿠키로 세션ID 포함하여 데이터를 응답
  3. 브라우저는 세션ID를 쿠키에 저장하고 있음
  4. 브라우저가 express(서버)에게 요청 할 때마다, 쿠키에 세션ID를 같이 보냄
  5. express(서버)는 보낸 세션ID가 존재하는지 확인
  6. 세션ID가 존재하면 로그인된 사용자만 볼 수 있는 데이터를 응답
  • res.locals (express-PUG)

    연결된 req.session 에 사용자가 입력한 정보를 저장한다.
    하지만 Controller(express) -> PUG(템플릿) 사이에서는 req.session을 사용하지 못한다. 따라서
    템플릿에서도 접근가능한 res.locals 객체에 session 정보를 담을 수 있다.
    	res.locals.isUser = Boolean(req.session.isUser)
    	res.locals.user = req.session.user 
    	...
  • MongoStore

    사용자가 로그인하여 입력한 req.session은 서버가 재시작되면 없어진다.
    따라서 세션정보를 MongoDB에 저장하여 로그인 유지기능을 구현한다.

- 깃헙/카카오/네이버 로그인 구현

  • 사이트마다 요청하는 정보(변수 config)는 조금씩 다르지만 흐름은 똑같다.
  • OAuth
    사용자가 사이트에 접속하여 권한(회원가입)을 얻으려고 할 때,
    사용자 동의하에 발급받은 토큰을 갖고 사이트-네이버간 사용하는 프로토콜
  • 네이버 로그인 API
    1. 유저가 사이트에서 네이버로 로그인하기 클릭
    2. 사이트에서 네이버 정보제공 사이트로 리다이렉트 (정보제공동의 요청)
    3. 유저가 네이버에게 사이트로 인증코드 요청 (동의)
    4. 네이버가 사이트에게 인증코드 발급
    5. 사이트는 인증코드와 함께 네이버에게 토큰발급 요청
    6. 네이버는 인증코드를 확인하고, 사이트에게 토큰 발급
    7. 사이트는 토큰을 통해 네이버 오픈 API 호출
    8. 사이트는 API를 통해 받은 정보를 토대로 사용자 로그인
// 1. 로그인 하기 클릭 시, Controller

// 네이버 연동 사이트
const baseUrl = "https://nid.naver.com/oauth2.0/authorize";
// 네이버가 원하는 정보
const config = {
    response_type: "code",
    client_id: process.env.NAV_CLIENT,
    state: process.env.COOKIE_SECRET,
    redirect_uri: `${process.env.HEROKU_SERVER}/users/naver/callback`,
};
const params = new URLSearchParams(config).toString();
// 2. 사이트가 네이버 연동 사이트로 리다이렉트
return res.redirect(`${baseUrl}?${params}`);

// 3-4. 사용자가 동의하면 아래 코드 실행

// 5-1. 사이트가 발급받은 인증코드를 갖고 네이버에게 토큰 발급 준비
const baseUrl = "https://nid.naver.com/oauth2.0/token";
const config = {
    grant_type: "authorization_code",
    client_id: process.env.NAV_CLIENT,
    client_secret: process.env.NAV_SECRET,
    code: req.query.code,
    state: process.env.COOKIE_SECRET,
};
const params = new URLSearchParams(config).toString();
const redirectUrl = `${baseUrl}?${params}`;

// 5-2. 사이트가 네이버에게 토큰 발급 요청
const tokenRequest = await (
    await fetch(redirectUrl, {
      method: "POST",
      headers: {
        Accept: "application/json",
      },
    })
  ).json();

  // 6. 토큰발급을 받았다면, 토큰을 통해 네이버 오픈 API 호출하여 사용자 정보 요청
  if ("access_token" in tokenRequest) {
    const { access_token } = tokenRequest;
    const apiUrl = "https://openapi.naver.com/v1/nid/me	";
    
    // 사용자 정보를 userData 변수에 담음
    const userData = await (
      await fetch(`${apiUrl}`, {
        headers: {
          Authorization: `Bearer ${access_token}`,
        },
      })
    ).json();
    

- webpack

JS, html, css, image와 같은 정적인 자원들을 최적화하는 패키지
파일간에 관계를 정의를 해주고, 압축 및 최적화를 통해 웹페이지 성능을 올려준다.

  • webpack이 해결해 주는 것들
    1. 자바스크립트 변수 유효 범위 설정
    2. 브라우저별 HTTP 요청 감소 효과
    3. 사용하지 않는 코드의 관리
    4.동적 로딩 & Lazy Loading - 사용자가 보고 있는 화면을 로딩

- heroku

실제 서버에 배포하는 것을 도와주는 클라우드 플랫폼이다.
단점으로는 느린 로딩속도가 있다. 그러한 이유로는
1. heroku 서버가 미국에 있다. (우리나라와 가까운 곳에 서버 설정 불가)
2. 방문자가 20분이상 들어오지 않으면 사이트 재가동에 30초가 걸린다.

- mongoDB Atlas

클라우드 데이터베이스 이다.
heroku에 서버를 배포하면 mongoDB를 배포할 수 있게 수정해야 한다.
지금까지의 DB는 로컬호스트에서만 작동하기 때문이다.

- AWS S3 (Simple Storage Service)

AWS가 제공하는 파일서버의 역할을 하는 서비스이다.

  • 사용이유
    업로드한 파일(video, img)들이 서버에 저장되게 된다면
    서버 재시작시(프로젝트 수정시), 업로드한 파일들이 없어진다.
    또한 파일의 용량이 크면 서버의 퍼포먼스에 영향을 끼칠 수 있다.
    따라서 업로드할 때, 파일서버에 파일들을 저장하고
    업로드한 파일들의 경로(주소)를 mongoDB에 저장하여 관리한다.

  • multer, multer s3, aws-sdk (버전이 동일해야함 3.x.x.., 3.x.x....)
    1. multer - 사용자가 업로드한 파일을 받아서 서버에 저장하는 미들웨어
    2. aws-sdk - 서버와 AWS 연결해준다.
    3. multer s3 - 서버가 받은 파일을 지정된 AWS 버킷에 저장한다.

profile
wannabe---ing

0개의 댓글