데브코스

[Day 40] Netlify Serverless Functions, 환경변수

라다디 2022. 12. 15. 17:15

Netlify Serverless Functions

보안을 위해 API_KEY와 같은 민감한 정보들이 노출되지 않도록 서버리스 함수를 적용해보자.

 

Netllify 서버를 통해 배포를 하지 않고도 배포 결과를 확인할 수 있도록 명령(script)를 등록한다. 

// package.json
  "scripts": {
    "dev": "webpack-dev-server --mode development",
    "dev:netlify": "netlify dev",
    "build": "webpack --mode production"
  },

해당 명령을 사용하려면 Netlify CLI를 설치해야 한다. 

 

npm i -D netlify-cli

 

Get started with Netlify CLI

Install our CLI (command line interface) and use it to run a local development environment, deploy your site, manage environment variables, and more.

docs.netlify.com

해당 패키지를 통해 로컬에 netlify server를 오픈할 수 있다. 

 

이제 루트 경로에 netlify.toml이라는 파일을 생성하고 기본적인 구성 옵션을 작성한다. 

# 제품모드 
[build]
  command = "npm run build" # 빌드 명령
  functions = "functions" # Netflify 서버리스 함수가 작성된 디렉토리 지정
  publish = "dist" # 프로젝트 빌드 결과의 디렉토리 지정 

# 개발모드 
[dev]
  framework = "#custom" # Netlify가 감지할 프로젝트 유형 지정
  command = "npm run dev" # 연결할 프로젝트의 개발서버를 실행하는 명령(script) 지정
  targetPort = 8080 # 연결할 프로젝트의 개발서버의 포트번호 지정 
  port = 5000 # 출력할 Netlify 서버의 포트번호를 지정 
  publish = "dist" # 프로젝트의 정적 콘텐츠 디렉토리를 지정
  autoLaunch = false # Netlify 서버가 준비되면 자동으로 브라우저를 오픈할 것인지 지정
  # 서버 환경에 배포하지 않아도 로컬 환경에서 테스트 가능

[참고] vscode 확장 프로그램 Better TOML을 설치하면 코드 하이라이팅이 된다.

 

 

Build functions

Create functions source files in TypeScript, JavaScript, and Go. Use environment variables with functions, manage dependencies, and test locally.

docs.netlify.com

루트 경로에 function 폴더를 생성하고 폴더 아래에 sample.js 파일을 만든다.

// functions/sample.js
exports.handler = async function () {
  return {
    statusCode: 200,
    body: JSON.stringify({
      name: 'sample',
      age: 85,
      email: 'sample@abc.com',
    })
  }
}

이제 npm run dev:netlify 명령을 입력하여 서버를 오픈한 뒤 http://localhost:5000/.netlify/functions/sample 주소로 이동하면 함수에서 반환하고 있는 객체 데이터가 출력되는 것을 볼 수 있다.

서버리스 함수를 통해 API 서버를 만든 것이다.

이런식으로 프론트엔드에서 노출하기 민감한 정보를 netlfy 서버로 이관해서 사용자에게 노출되지 않게 만들어주고, netlfy 서버가 프론트엔드에서 필요한 정보만 내어주도록 만들어주면 된다.

 

이제 이전 실습에서 작성한 노션 클론 프로젝트에 서버리스 함수를 적용해보자. 

functions 폴더 밑에 workspace.js 파일을 생성한 뒤 기존 store/workspace.js에 있던 request 함수의 코드를 옮길 것이다.

// 기존 store/workspace.js
async function _request(options) {
  const { id = '' } = options
  return await fetch(`https://kdt-frontend.programmers.co.kr/documents/${id}`, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      'x-username': 'hyejun'
    },
  }).then(res => res.json())
}

 

Netlify에서 제공하는 서버리스 함수는 자바스크립트의 fetch함수를 사용할 수 없기 때문에 axios 패키지를 설치하였다.

npm i axios

// functions/workspace.js
const axios = require('axios')

exports.handler = async function (event) {
  const options = JSON.parse(event.body)
  const { id = '', method, body } = options
  const { data } = await axios({
    url: `https://kdt-frontend.programmers.co.kr/documents/${id}`,
    method,
    headers: {
      'Content-Type': 'application/json',
      'x-username': 'hyejun'
    },
    data: body,
  })
  return {
    statusCode: 200,
    body: JSON.stringify(data)
  }
}

그리고 기존 store/workspace.jsrequest함수는 다음과 같이 수정한다.

async function _request(options) {
  return await fetch('/.netlify/functions/workspace', {
    method: 'POST',
    body: JSON.stringify(options)
  }).then(res => res.json())
}

이제 개발자 도구의 네트워크 탭을 열어봐도 x-username이나 API_ENDPOINT같은 민감한 정보가 노출되고 있지 않다.

 

환경변수 적용

서버에서 민감한 정보가 드러나는 것은 막았지만 workspace.js파일의 코드에는 여전히 민감한 정보가 드러나있다.

이 정보를 감추기 위해서 환경 변수를 적용해보자.

 

npm i -D dotenv

패키지 설치 후 프로젝트의 루트 경로에 .env 파일을 생성한 뒤 감추고 싶은 정보를 작성한다.

API_ENDPOINT=https://kdt-frontend.programmers.co.kr/documents/
API_KEY=hyejun

 

환경 변수 정보를 가져오기 위해서 다음과 같이 작성한다. 

config 메소드가 현재 프로젝트 환경에 있는 .env 파일을 읽어서 그것을 process.env라는 전역 변수로 넣어주게 된다.

require('dotenv').config()
const axios = require('axios')
const { API_ENDPOINT, API_KEY} = process.env

exports.handler = async function (event) {
  const options = JSON.parse(event.body)
  const { id = '', method, body } = options
  const { data } = await axios({
    url: `${API_ENDPOINT}${id}`,
    method,
    headers: {
      'Content-Type': 'application/json',
      'x-username': API_KEY
    },
    data: body,
  })
  return {
    statusCode: 200,
    body: JSON.stringify(data)
  }
}

그리고 .env 파일은 깃허브에 업로드가 되지 않도록 .gitignore에 작성한다.

 

그렇다면 환경변수 정보를 깃허브에 올리지 않고 있는데 netlify의 서버리스 함수는 어떻게 환경 변수를 알아내는 것일까?

로컬에서 개발을 할 때는 .env 파일을 제공해서 config 메소드로 읽을 수 있게 만들어주고, 실제 netlfy 서비스에서는 환경변수를 직접 작성해줘야 한다.

 

Netlify에서 site settings / build & deploy / environment 탭으로 이동하여 다음과 같이 환경변수의 키와 값을 작성한다.

이런 데이터들은 Netlify 서버의 환경변수로 지정을 하는 것이 때문에 Netlify 서버가 해킹되지 않는 이상 노출될 일이 없다.

 


출처: 프로그래머스 프론트엔드 데브코스 

[Day 40] Vue (8)