휴대폰 본인인증 연동하기


이 문서는 휴대폰 본인인증 기능을 구현하는 방법을 설명합니다.휴대폰 본인인증 서비스란 본인 명의로 개통한 휴대폰을 이용하여 최소한의 개인정보를 입력하는 인증 절차를 거쳐 본인 여부와 입력한 정보의 정확성을 확인하여 주는 서비스입니다.

고객은 웹사이트에 가입, 결제, 또는 성인 인증 등을 위해 본인인증을 시행합니다. 본인인증은 모바일 기기에 설치된 본인인증 전용 앱을 이용하거나 사용자 본인 정보(이름, 생년월일, 휴대폰번호)를 인증요청 페이지에 입력한 후 문자로 온 인증번호를 기입하는 방식으로 이루어집니다.

STEP1아임포트 라이브러리 추가하기
client-side

본인인증 페이지에 아임포트 라이브러리를 추가합니다. 휴대폰 본인인증 기능은 아임포트 JavaScript v1.1.4부터 지원합니다.

최신 라이브러리 버전 정보아임포트 JavaScript SDK Release Notes 페이지에서 확인하세요.
  <!-- jQuery -->
  <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>
  <!-- iamport.payment.js -->
  <script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-{SDK-최신버전}.js"></script>

jQuery 1.0 이상이 설치되어 있어야 합니다.
STEP2본인인증 준비하기
client-side

본인인증 페이지에 가맹점 식별코드를 이용하여 IMP 객체를 초기화합니다.
  var IMP = window.IMP; // 생략 가능
  IMP.init("{가맹점 식별코드}"); // 예: imp00000000
STEP3본인인증 요청하기
client-side

필요한 인증 정보로 IMP.certification팝업 또는 리디렉션 방식으로 호출하여 본인인증 요청을 합니다. 리디렉션 방식은 아임포트 JavaScript v1.1.7부터 지원합니다.

팝업(기본) 방식

휴대폰 본인인증 팝업창이 열리고, 본인인증를 완료하면, 두 번째 인자로 지정된 callback 함수가 실행됩니다.

리디렉션 방식 (모바일 환경에서만 적용)

모바일 환경에서 param.popupfalse(기본값)로 설정하면 본인인증 페이지로 리디렉션되고, 본인인증을 완료하면, param.m_redirect_url로 다시 리디렉션됩니다. param.popuptrue로 설정하면 팝업(기본) 방식으로 작동합니다.

WebView 등 팝업이 차단되는 환경에서는 popup : false로 설정하는 것을 권장합니다.

필요한 인증 정보로 IMP.certification을 호출하여 본인인증 요청을 합니다.

  // IMP.certification(param, callback) 호출
  IMP.certification({ // param
    merchant_uid: "ORD20180131-0000011", // 주문 번호
    m_redirect_url : "{리디렉션 될 URL}", // 모바일환경에서 popup:false(기본값) 인 경우 필수, 예: https://www.myservice.com/payments/complete/mobile
    popup : false // PC환경에서는 popup 파라메터가 무시되고 항상 true 로 적용됨
  }, function (rsp) { // callback
    if (rsp.success) {
      ...,
      // 인증 성공 시 로직,
      ...
    } else {
      ...,
      // 인증 실패 시 로직,
      ...
    }
  });
STEP4인증 정보 전달하기
client-side

팝업으로 전달하기

인증 프로세스가 완료되면 반환되는 응답 객체(rsp)의 인증 성공 여부에 따라 처리 로직을 callback 함수에 작성합니다. 요청이 성공했을 경우에 인증번호(imp_uid)를 서버에 전달하는 로직을 다음과 같이 작성합니다.
  IMP.certification({
    /* ...중략... */
  }, function (rsp) { // callback
    if (rsp.success) { // 인증 성공 시
      // jQuery로 HTTP 요청
      jQuery.ajax({
        url: "{서버의 인증 정보를 받는 endpoint}", // 예: https://www.myservice.com/certifications
        method: "POST",
        headers: { "Content-Type": "application/json" },
        data: { imp_uid: rsp.imp_uid }
      });
    } else {
      alert("인증에 실패하였습니다. 에러 내용: " +  rsp.error_msg);
    }
  });

리디렉션으로 전달하기

IMP.certification 호출 시 설정한 param.m_redirect_url로 인증 정보와 함께 다음과 같이 리디렉션됩니다.
GET {m_redirect_url}?imp_uid={}&merchant_uid={본인인증 건의 merchant_uid}&success={true 또는 false}
STEP5인증 정보 조회 및 활용하기
server-side

서버는 클라이언트로 부터 인증 정보를 수신한 후 imp_uid로 인증 정보를 조회하여 고객의 정보를 가져옵니다.
1인증번호 추출하기
서버에서 인증번호(imp_uid)를 전달받는 API endpoint를 작성합니다.
  app.use(bodyParser.json());
  ...
  // "/certifications"에 대한 POST 요청을 처리하는 controller
  app.post("/certifications", async (request, response) => {
    const { imp_uid } = request.body; // request의 body에서 imp_uid 추출
  })
2인증 정보 조회하기
아임포트 서버에서 인증 정보를 조회하기 위해서 먼저 REST API access token을 발급받습니다.

발급받은 액세스 토큰(access token)과 인증번호(imp_uid)로 REST API(GET https://api.iamport.kr/certifications/${imp_uid})를 호출하여 인증 정보를 조회하는 예제입니다.
  app.use(bodyParser.json());
  ...
  // "/certifications"에 대한 POST 요청을 처리하는 controller
  app.post("/certifications", async (request, response) => {
    const { imp_uid } = request.body; // request의 body에서 imp_uid 추출
    try {
      // 인증 토큰 발급 받기
      const getToken = await axios({
        url: "https://api.iamport.kr/users/getToken",
        method: "post", // POST method
        headers: { "Content-Type": "application/json" }, // "Content-Type": "application/json"
        data: {
          imp_key: "imp_apikey", // REST API키
          imp_secret: "ekKoeW8RyKuT0zgaZsUtXXTLQ4AhPFW3ZGseDA6bkA5lamv9OqDMnxyeB9wqOsuO9W3Mx9YSJ4dTqJ3f" // REST API Secret
        }
      });
      const { access_token } = getToken.data.response; // 인증 토큰
      ...
      // imp_uid로 인증 정보 조회
      const getCertifications = await axios({
        url: \`https://api.iamport.kr/certifications/\${imp_uid}\`, // imp_uid 전달
        method: "get", // GET method
        headers: { "Authorization": access_token } // 인증 토큰 Authorization header에 추가
      });
      const certificationsInfo = getCertifications.data.response; // 조회한 인증 정보
      ...
    } catch(e) {
      console.error(e);
    }
  });
3인증 정보 활용하기
조회한 인증 정보에서 다음의 고객 정보를 추출하여 서비스에 필요한 로직을 작성합니다.
  • name: 이름
  • gender: 성별
  • birth: 생년월일
  • unique_key: CI 값과 동일. 온라인 주민번호와 같은 개인고유식별키
  • unique_in_site: DI 값과 동일. 상점아이디(사이트)별로 할당되는 식별키
위의 정보 외에 휴대폰 번호(phone) 및 통신사(carrier) 또는 외국인(foreigner) 여부는 개인정보 제공동의 약관을 사이트에 게재한 후 cs@iamport.kr로 신청하여 취득할 수 있습니다.고객 정보를 추출하여 활용하는 예제입니다. 필요 시, 예제와 같이 고객 정보를 사용하여 연령 제한이나 1인1계정 정책을 검사할 수 있습니다.

<가맹점 정보>
  • 상호명 :
  • 사업자번호 :
  • 본인인증용 다날 상점ID(CPID) :
  • 개인정보취급방침 url : 앱서비스로 URL형태로 전달이 어려우신 경우 '개인정보취급방침' 경로를 캡쳐하여 전달주시기 바랍니다.
<참고 - 아임포트 이용 가맹점의 개인정보처리방침 적용 예시>
  • (주)마플 : https://marpple.shop/kr/@/privacy
  • (주)브레이브모바일 / 숨고 : https://soomgo.com/terms/privacy
  • (주)마켓잇 : https://static.marketit.asia/static/privacy-terms.pdf
해당 부분은 당사 계약 이후 다날PG사로 요청 그 후 승인이 완료되면 이용 가능한 점 참고해 주시기 바랍니다.
  // "/certifications"에 대한 POST 요청을 처리하는 controller
  app.post("/certifications", async (request, response) => {
    const { imp_uid } = request.body; // request의 body에서 imp_uid 추출
    try {
      // 인증 토큰 발급 받기
      /* ...중략... */
      // imp_uid로 인증 정보 조회
      /* ...중략... */
      const certificationsInfo = getCertifications.data.response; // 조회한 인증 정보
      // unique_key: 개인식별 고유 키, unique_in_site: 사이트 별 개인식별 고유 키
      const { unique_key, unique_in_site, name, gender, birth } = certificationsInfo;
      ...
      // 연령 제한 로직
      if (new Date(birth).getFullYear() <= 1999) {
        // 연령 만족
      } else {
        // 연령 미달
      }
      ...
      // 1인 1계정 허용 로직
      // DB에서 unique_key 조회 후 가입여부 검사
      Users.find({ certificationKey: unique_key })
      .then((user) => {
        if (!user) {
          // 신규 고객
        } else {
          // 이미 가입된 고객
        }
      });
    } catch(e) {
      console.error(e);
    }
  });