---
title: Google Form과 NAC REST API 를 이용한 IP 신청 (Sheet 버전)
description: Google Form과 Genian NAC의 RESTful API를 활용한 고객 맞춤 서비스 아이디어를 소개합니다.
---

[지니언스 기술 블로그 ](https://www.genians.co.kr/blog)

# [Google Form과 NAC REST API 를 이용한 IP 신청 (Sheet 버전)](https://www.genians.co.kr/blog/nac-api_google-form)

 작성자: [Genians](https://www.genians.co.kr/blog/author/genians) | Oct 2, 2024 12:00:00 AM

제품을 개발할 때 다양한 고객들의 요구 사항을 모두 수용하기는 현실적으로 어렵습니다. 하지만 연동을 위한 API 들이 추가되고 편하고 접근성이 좋은 서비스들이 시중에 나와있기 때문에 이들을 이용하여 고객의 요구 사항을 직접 구현해볼 수 있습니다.

이에 Google Form과 RESTful API를 활용한 고객 맞춤 서비스 아이디어를 소개하려고 합니다. 본 문서는 이 서비스의 개념, 시나리오, 구현 방법 등을 상세히 설명하여 NAC와 IP 신청 시스템을 운영 시 참고하실 수 있도록 작성되었습니다.

 

## 개념 소개

1. Genian NAC의 RESTful API  
   내부 자산과 사용자를 보호하고 기업 자원을 안전하게 사용할 수 있도록 지원하는 유무선 네트워크 접근제어 솔루션인 Genian NAC 에서는 해당 자원들을 접근하고 통제할 수 있는 기능 및 IP 신청 등을 REST API로 제공하고 있습니다.
2. Google Form  
   Google Form은 구글에서 제공하는 무료 웹 기반 설문조사 도구 입니다. 간편한 설문지 생성, 실시간 응답 수집, 다양한 공유 옵션, 통계분석 기능과 부가기능을 제공합니다. 설문지 생성 시 Script가 동작하도록 설정할 수 있으며 구글폼을 통해 사용자에게 IP 신청을 받는 용도로 활용합니다.
3. Google Apps Script  
   Google에서 제공하는 클라우드 기반 스크립팅 플랫폼 입니다. 이를 활용하여 Google 제품군과 통합하여 맞춤형 애플리케이션을 빌드할 수 있습니다.  
   Google 워크스페이스, Gmail, 드라이브, Sheets 등의 통합환경에서 Javascript 기반 스크립트를 작성하며 특정 이벤트에 맞춰 스크립트를 실행하는 트리거와 이벤트 및 API 연동을 클라우드 기반으로 무료 및 저비용으로 사용할 수 있는 도구 입니다.

 

## 시나리오

본 문서에서 다루는 시나리오는 이와 같습니다.

| 1. 사용자가 Google Form 으로 신청 내용 작성 2. Google Sheets 에 신청 내용 등록 3. 신청한 내용을 바탕으로 IP 신청 4. 관리자가 Google Sheets에서 승인으로 값 변경 5. 관리자가 승인한 IP 신청서 승인 |
| --- |

간략하게 그림으로 표현하면 아래와 같습니다.

[그림 1] Google Form과 RESTful API를 활용한 고객 맞춤 서비스 시나리오

## 사전 준비 및 구현

### **1. Genian NAC**

Google Apps Script에서 NAC의 API를 호출하기 위해서는 네트워크 접근이 가능해야 하기 때문에 클라우드 기반의 NAC 환경이거나 NAC에 접근할 수 있도록 도메인 설정을 먼저 해야 합니다. 여기에서는 접근 편의성을 위해 Test용 Cloud NAC를 생성하여 진행합니다.

(1) Cloud NAC 사이트 생성

- genians ([https://www.genians.com/](https://www.genians.com/) ) 사이트에서 계정 생성 및 사이트 생성

[그림 2] Cloud NAC 사이트 생성

(2) 센서 설정 및 API Key 발급

- IP 신청을 하기 위해서는 관리하고 있는 네트워크에 NAC 센서를 연결하여 생성한 사이트에 등록해야 합니다. NAC 센서 생성 및 설정은 Genian NAC Documents를 참고하세요.
- API 연동을 위해서는 관리자의 API Key를 생성해야 합니다.  
  관리 > 사용자 > 관리자의 상세 화면에서 API Key를 생성할 수 있습니다.

**[그림 3] API Key 생성 화면**

-   해당 Key는 생성할 때만 확인할 수 있기 때문에 분실하지 않도록 보관합니다.

 

(3) 센서 Node ID 확인

- IP 신청을 할 때 NAC 센서를 선택해야 하는데 선택할 때의 Key가 되는 Node ID를 확인합니다.
- 시스템 > 센서 설정 > 센서 상세 화면의 노드 ID 확인

[그림 4] 노드 ID 확인 화면

### **2. Google Form**

(1) 사용자에게 IP 신청을 받을 수 있는 Google Form의 항목을 설정합니다.

- Google Drive 의 메뉴에서 Google 설문지 메뉴 선택

[그림 5] Google Drive 설문지

(2) IP 신청서 작성 시 필수 입력이 되는 부분을 설정합니다.

- 각 사이트마다 요구 사항은 다를 수 있으며 환경에 맞게 구성합니다.
- 이번 문서에서는 기본적인 항목을 기반으로 설정하였고 설정 사항은 아래와 같습니다.

| 사용위치 : 드롭다운 | 사용하고 있는 센서를 추가합니다. 여러 항목을 선택할 수 있도록 드롭다운을 사용했으며 구분을 위해 IP 주소를 라벨로 지정했습니다. |
| --- | --- |
| 사용자 ID : 단답형 텍스트 | 사용자의 ID를 입력합니다. |
| 용도 : 드롭다운 | 유동, 고정 IP 사용인지 용도를 선택할 수 있습니다. |
| IP 주소 : 단답형 텍스트 | 고정 IP 용도인 경우 IP를 입력받습니다. |
| MAC 주소 :단답형 텍스트 | 고정 IP 용도인 경우 MAC 주소를 입력 받습니다. |
| 이메일 : 단답형 텍스트 | 신청 결과를 받을 이메일 주소를 입력 받습니다. |

 

[그림 6] IP 신청서 화면

**(3) 응답결과에 대한 Sheets를 생성합니다.**

- 응답 > Sheets에서 보기 선택

[그림 7] IP신청 응답결과 화면

**(4) Sheets 에서 컬럼 두개를 추가 합니다.

**

**[그림 8] IP 신청 결과 Sheets 화면

**

① 승인여부 컬럼  
관리자가 승인 여부를 선택할 수 있도록 컬럼을 추가합니다. (드롭다운 메뉴로 추가하면 편리합니다.)

[그림 9] Sheet 드롭다운 메뉴 추가

② idx 컬럼  
신청서 추가 후 발급받은 idx 값을 업데이트 할 컬럼 입니다.

### 3. Apps Script

- 설문이 작성되어 시트에 내용이 저장될 때마다 실행될 스크립트를 작성합니다.
- 실행할 스크립트 종류는 두 종류 입니다.
  
  ① 신청서 작성 시 신청서 등록 스크립트
  
  ② 관리자 승인 시 신청서 승인 스크립트

 

**(1) Sheets 메뉴 > 확장 프로그램 > Apps Script 를 선택합니다.**

**[그림 10] Apps Script 확장 프로그램  
**

 

(2) 스크립트를 작성하기 전 NAC의 Swagger 페이지에서 사용할 API를 확인합니다.

- swagger는 API 를 문서화해주는 도구이며 [https://도메인/mc2/swagger/index.html](https://xn--hq1bm8jm9l/mc2/swagger/index.html) 에서 확인할 수 있습니다.

[그림 11] Genian NAC의 Swagger 페이지 화면

- 생성과 승인을 하기 위해 POST /mc2/rest/applications/ips(신청서 생성) 와 PUT /mc2/rest/applications/ips/신청서idx(신청서 상태 수정) API를 확인합니다.

 

(3) Google form이 작성될 때마다 실행될 스크립트를 작성합니다.

- IP 신청서 등록

| function onFormSubmit(e) {      const itemResponses = e.namedValues;       // 관리자의 API Key를 생성한 뒤 api 호출 시 사용할 수 있도록 선언한다.       const API_KEY = "[apiKey]"       // REST API 를 호출할 url       const url = "https://[도메인]/mc2/rest/applications/ips";          const applyResJson = applyIpApplication(url, API_KEY, itemResponses);       if(applyResJson !==  null) {           const idx = applyResJson.ipApps[0].idx;           const sheet = e.range.getSheet();           const row = e.range.getRowIndex();           sheet.getRange(row, 9).setValue(idx);        }     } /**   * IP 신청서 신청 후 응답값을 json 객체로 반환   */ function applyIpApplication(_url, apiKey, itemResponses) {      const url = _url + "?apiKey=" + apiKey;      const payload = getApplicationPayload(itemResponses);       // REST API 호출       const options = {          "method": "POST",          "contentType": "application/json;charset=UTF-8",          "headers": {               "accept": "application/json;charset=UTF-8"          },          "payload": payload        };       const response = UrlFetchApp.fetch(url, options);       let resJson = null;       try {           resJson = JSON.parse(response.getContentText());       } catch(e) {           resJson = null;       }       return resJson;       }    /**      * IP 신청서 신청 시 입력된 값을 json string 으로 변환      */    function getApplicationPayload(itemResponses) {         // 센서의 nid을 가져올 수 있도록 객체로 미리 선언        const sensorDatas = {'172.29.50.52': '0d300156-7c51-103e-8002-080027a65e65-cc2d2503',                                                    '172.29.50.53': '0d300156-7c51-103e-8002-080027a65e65-cc2d2504'};         // 용도의 value 값 선언        const purposeDatas = {'유동IP사용': 'USERIP_VARIABLE',                                                            '고정IP사용': 'USERIP_STATIC'};         // 응답 데이터 가공        const purposeType = itemResponses["용도"][0];        const data = {};        // 신규신청 : 1        data["appType"] = 1;        data["sensorNid"] = sensorDatas[itemResponses["사용위치"][0]];        data["id"] = itemResponses["사용자 ID"][0];        data["applicantId"] = itemResponses["사용자 ID"][0];        data["purposeCode"] = purposeDatas[itemResponses["용도"][0]];        if(purposeType === '고정IP사용') {            data["ipStr"] = itemResponses["IP 주소"][0];            data["mac"] = itemResponses["MAC 주소"][0];         }        data["alarmEmail"] = itemResponses["이메일"][0];         const payload = JSON.stringify([             data         ]);         return payload;       } |
| --- |

- function 설명

| onFormSubmit() | Google form이 작성되는 실행되는 진입점이 되는 function |
| --- | --- |
| applyIpApplication() | 신청서 API를 호출하는 function. 작업이 완료되면 결과값을 json 형태로 리턴합니다. |
| getApplicationPayload() | 신청서 API 호출 시 form에 입력된 정보를 바탕으로 파라미터를 생성합니다. |

- 사전 정의한 정보

|   const sensorDatas = {'172.29.50.xx': '센서 Node ID',                                             '172.29.50.xx': '센서 Node ID'};   // 용도의 value 값 선언   const purposeDatas = {'유동IP사용': 'USERIP_VARIABLE',                                                   '고정IP사용': 'USERIP_STATIC'}; |
| --- |

- - IP 신청을 할 때 센서의 Node ID 값을 파라미터로 전송해야 하는데 form에 Node ID를 노출하는 것은 사용자가 인식하기 어려운 정보이기 때문에 해당 부분은 치환이 될 수 있도록 js 객체로 사전에 정의해 놓았습니다.
    - 용도의 Key 값도 사용자가 선택한 라벨이 치환될 수 있도록 사전에 정의해 놓습니다.

- IP 신청 승인

| /**  * 시트에서 승인 컬럼 값이 변경되면 호출  * @param {e} 이벤트 객체  */  function onEdit(e) {       const sheet = e.source.getActiveSheet();       const targetColumn = 8; // idx 컬럼       const editedRow = e.range.getRow();       const val = e.range.getValue();          // 수정된 셀이 타겟 컬럼에 있는 경우에만 처리       if (val === '승인') {          const record = sheet.getRange(editedRow, 1, 1, sheet.getLastColumn()).getValues()[0];          const idx = record[targetColumn];          if(idx !== '') {              approveIpApplication(idx);          }        }   }   /**    * IP 신청서 승인    */  function approveIpApplication(idx) {       // 관리자의 API Key를 생성한 뒤 api 호출 시 사용할 수 있도록 선언한다.       const API_KEY = "[apiKey]"       const apiUrl = "https://[도메인]/mc2/rest/applications/ips/" + idx + "?apiKey=" + API_KEY;       const options = {            "method": "PUT",            "contentType": "application/x-www-form-urlencoded",            "headers": {                 "accept": "application/json;charset=UTF-8"             },             "payload": "cmd=approve"         };         try {             const response = UrlFetchApp.fetch(apiUrl, options);              } catch (err) {             Logger.log("Error: " + err);          }     } |
| --- |

- function 설명

|    onEdit() | - 시트의 컬럼값을 관리자가 수정했을때 호출되는 function - 관리자가 수정한 컬럼이 승인여부 컬럼이면서 승인으로 값을 변경할 경우, approveIpApplication() function을 호출한다. |
| --- | --- |
| approveIpApplication() | - 선택한 레코드의 IP 신청서를 승인한다. |

 

(4) 트리거로 등록

- 트리거 메뉴로 이동합니다.

[그림 12] Apps Script 화면

- 트리거 추가
  
    - IP 신청서 등록 트리거 (이벤트 유형: 양식 제출 시)

**[그림 13] IP신청서 승인 트리거 화면 - 함수: onFormSubmit

**

| 실행할 함수 선택 | 스크립트에 작성한 onFormSubmit() 선택 |
| --- | --- |
| 실행할 배포 | Head |
| 이벤트 소스 선택 | 스프레드시트에서 |
| 이벤트 유형 선택 | 양식 제출 시 |

 

- - IP 신청서 등록 트리거 (이벤트 유형: 수정 시)

**[그림 14] IP신청서 승인 트리거 화면 - 함수: onEdit

**

| 실행할 함수 선택 | 스크립트에 작성한 onEdit() 선택 |
| --- | --- |
| 실행할 배포 | Head |
| 이벤트 소스 선택 | 스프레드시트에서 |
| 이벤트 유형 선택 | 수정 시 |

- 설문 작성 및 실행 확인
  
    - 실행 확인  
      ① 설문을 작성 후 확인  
      ② 시트에서 승인 후 확인

[그림 15] Apps Script 실행 화면

- Logger.log 로 확인할 내용을 작성해 놓으면 실행에서 확인할 수 있습니다.

 

(5) NAC에서 IP 신청 결과 확인

- 관리 > 신청 > IP 사용 신청서 > 결과 조회 메뉴 이동
- 승인된 신청서 확인

[그림 16] Genian NAC - IP 사용신청서 결과 화면

 

## 마치며

Google Apps Script와 Genian NAC의 REST API를 활용하여 IP 신청서를 생성하고 승인하는 과정을 경험해 보았습니다. 이처럼 Google Apps Script뿐만 아니라 REST API를 호출할 수 있는 다양한 도구들과 Genian NAC를 연동하면, 무궁무진한 활용 방법을 모색해 볼 수 있을 것입니다.

Genian NAC의 기존 UI에서 제공하는 기능 만으로는 한계가 있지만, REST API를 적극 활용한다면 고객의 요구 사항을 보다 폭넓게 수용할 수 있을 것입니다. 예를 들어 화면 개선이 어려운 상황이라면, 연동을 통해 해결책을 모색해볼 수 있습니다.

고객 환경에 맞는 최적의 솔루션을 제공하기 위해서는 때로는 기존의 틀을 벗어난 새로운 접근이 필요할 것입니다. 위 문서를 토대로 고객의 불편 사항을 꼭 해결할 수 있는 방안이 없는지 아이디어를 발휘해 보시면 어떨지 생각하며 이 글을 마칩니다.

 

### 글쓴이.한동선

지니언스 기술연구소에서 NAC 관련 제품 개발 및 기술 연구를 담당하고 있습니다.

 

<https://www.genians.co.kr/hs/cta/wi/redirect?encryptedPayload=AVxigLLUnZO5nwds5KGCVMzY52zPtyj9zyHlxFCidcnxWMwj1tY%2FCqIvImlRQEC7SF3XS5nXGzWfiQihyzopQq%2FvYnNmF2i%2F2RFdAtex4InRAf6jx1XKB5p4vAy6V160ZSKD9nJ0yMvy3AY0SfLvXrhX4nRTHS%2Fr5s6pwyUHoazB8YOB6zoxPIUZ1Htiy7p9bBCgauyEoXOXfLFvOQ%3D%3D&webInteractiveContentId=126857649035&portalId=22120960>

[전체 게시물 보기](https://www.genians.co.kr/blog/nac-api_google-form)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Genians"
  },
  "dateModified" : "2024-12-11T00:34:45.492Z",
  "datePublished" : "2024-10-02T00:00:00Z",
  "headline" : "Google Form과 NAC REST API 를 이용한 IP 신청 (Sheet 버전)",
  "image" : {
    "@type" : "ImageObject",
    "height" : 301,
    "url" : "https://22120960.fs1.hubspotusercontent-na1.net/hubfs/22120960/%ED%8A%B9%EC%84%B1%ED%99%94%20%EC%8D%B8%EB%84%A4%EC%9D%BC%20%281%29-3.png",
    "width" : 481
  },
  "mainEntityOfPage" : "https://www.genians.co.kr/blog/nac-api_google-form",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "지니언스 기술 블로그"
  }
}
```