Node- sms, naver SENS

참고
[1] https://guide.ncloud-docs.com/docs/sens-sens-1-3
[2] https://api.ncloud-docs.com/docs/ai-application-service-sens-smsv2


개요

  • 최근에는 어플리케이션 개발에 있어서 본인 인증을 위한 전화번호 인증이 법적으로 필수가 되어가고 있다.
  • 네이버 클라우드의 SENS(Simple and Easy Notification Services)를 통해 전화번호 인증 프로세스를 만들자.

네이버 클라우드 서비스

  • 네이버 클라우드 서비스에서 제공하는 Api들을 이용하기 위해서는 네이버 클라우드 서비스에 계정 등록 및 계정의 인증키가 필요하다.
  • 인증키에는 Access key와 Secret Key가 있으며, api들을 사용할 시 본인 인증 수단으로 사용된다.
  • SENS 서비스의 SMS 인증 프로세스를 이용하고 싶으면 네이버에서 제공하는 가이드를 따르자.

메시지 발송 api

  • 가이드 참고
  • 요청 URL은 다음과 같다.
  • Timestamp 는 현재 시간을 String으로 표시한 것.
  • iam access 는 현재 이 계정의 access key를 담은 것.
  • signature 는 Access Key Id와 맵핑되는 SecretKey로 암호화한 서명. HMAC 암호화 알고리즘은 HmacSHA256 사용한다.
  • url 중에 service_id에 SENS sevice id 를 넣어야 한다.
    POST  
    https: `//sens.apigw.ntruss.com/sms/v2/services/${serviceId}/messages`
    // Headers
    "Content-Type": "application/json; charset=utf-8"  
    "x-ncp-apigw-timestamp": {Timestamp}  
    "x-ncp-iam-access-key": {Sub Account Access Key}  
    "x-ncp-apigw-signature-v2": {API Gateway Signature}  
    
  • 결론적으로 요청하는 코드는 아래와 같다.
  • hmac.update(문자열)로 암호화를 하는 것이기 때문에 hmac 안에 들어가는 인자의 순서와 형태는 매우 중요하다.(url2로 나누어져있는 이유)
  • signature를 사용해 패킷을 검증하는 것이기 때문에 약속(순서와 형태)을 잘 지키자. 약속은 보고서에 나와있다.
  • 헤더에 암호화 알고리즘관련 정보가 들어있지 않기 때문에 암호화 알고리즘은 반드시 SHA256을 사용해야 한다.
  • space, newline 같은 사소한 정보도 들어가야만 올바르게 암호화 및 인증절차를 수행할 수 있다.
    const user_phone_number = req.body.user_phone_number;
    const serviceId = process.env.SMS_SERVICE_ID;
    const access_key = process.env.SMS_ACCESS_KEY;
    const secret_key = process.env.SMS_SECRET_KEY;
    const sens_call_number = process.env.MY_PHONE;
    const timestamp = Date.now().toString();
    const method = "POST";
    const url = `https://sens.apigw.ntruss.com/sms/v2/services/${serviceId}/messages`;
    const url2 = `/sms/v2/services/${serviceId}/messages`;
    const space = " ";
    const newLine = "\n";
    const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secret_key);
    ////
    hmac.update(method);
    hmac.update(space);
    hmac.update(url2);
    hmac.update(newLine);
    hmac.update(timestamp);
    hmac.update(newLine);
    hmac.update(access_key);
    const hash = hmac.finalize();
    const signature =  hash.toString(CryptoJS.enc.Base64);
    const verificationCode = getRandomNumber(6);
    ////
    const sms_res = await axios({
    method: method,
    url: url,
    headers: {
      "Contenc-type": "application/json; charset=utf-8",
      "x-ncp-iam-access-key": access_key,
      "x-ncp-apigw-timestamp": timestamp,
      "x-ncp-apigw-signature-v2": signature,
    },
    data: {
      type: "SMS",
      contentType:"COMM",
      countryCode: "82",
      from: sens_call_number,
      content: `인증번호는 [${verificationCode}] 입니다.`,
      messages: [{ to: `${user_phone_number}` }],
    }, 
    });
    
  • 요청 메소드 외에 다른 메소드(메시지 발송 요청 조회, 메시지 발송 결과 조회 등등)들은 가이드 북을 참고한다.