캡챠의 경우 사용자의 자동입력 방지를 위해 주로 사용되는 기능으로 네이버에서는 이미지 와 음성 캡챠 API를 제공해주고 있으며 오늘 알아볼 예제는 이미지를 이용한 캡챠이다.
캡챠 하면 네이버보다 조금더 알려진 구글에서 제공하는 리캡챠 API가 있다. 흔히 `로봇이 아닙니다` 로 불리는 이 리캡챠는 사이트 곳곳에서 많이 볼 수 있는데 해당 기능 구현을 자세히 알아보고 싶을 경우 아래의 포스팅을 확인해보기 바란다.
오늘 알아볼 네이버 캡챠 이미지 API같은 경우 총 3가지(키값 발급 + 이미지 요청 + 인증 결과 ) API 연동이 필요하며 해당 API 요청은 일 1,000건이라는 제한사항이 있어 실 서비스시에는 유료전환에 대한 고려가 필요하다.
<?php # https://developers.naver.com/docs/utils/captcha/reference/ 참고
define('NV_CLIENT_ID', '');
define('NV_CLIENT_SECRET', '');
$nkey = request_nkey();
$ncaptcha = request_ncaptcha($nkey);
// 캡차 키 발급 요청
function request_nkey(){
$url = 'https://openapi.naver.com/v1/captcha/nkey?code=0';
// 요청
$response = request_curl($url); // ex) Array ( [rst] => success [data] => {"key":"v2klm4SGVHG5tiQ9"} )
if( $response['rst'] != 'success'){ return false; } // 메시지 echo $response['msg'];
$data = json_decode($response['data'],true);
if( $data['errorCode'] > 0){ // ex) Array ( [errorMessage] => NID AUTH Result Invalid (1000) : Authentication failed. (인증에 실패했습니다.) [errorCode] => 024 )
return false;
}
return $data['key'];
}
// 캡차 이미지 요청
function request_ncaptcha($key = false){
if($key == false){ return false; }
$url = 'https://openapi.naver.com/v1/captcha/ncaptcha.bin?key='.$key;
// 요청
$response = request_curl($url); // 성공시 이미지 데이터
if( $response['rst'] != 'success'){ return false; } // 메시지 echo $response['msg'];
$data = json_decode($response['data'],true); // ex) Array ( [result] => [errorMessage] => Invalid key. [errorCode] => CT001 )
if( $data['result'] === false){
return false;
}
return $response['data'];
}
// 사용자 입력값 검증 요청
function request_nvalid($key = false, $value = false){
if($key == false || $value == ''){ return false; }
$url = 'https://openapi.naver.com/v1/captcha/nkey?code=1&key='.$key."&value=".$value;
// 요청
$response = request_curl($url); // 성공시 이미지 데이터
if( $response['rst'] != 'success'){ return false; } // 메시지 echo $response['msg'];
$data = json_decode($response['data'],true); // ex) Array ( [result] => [errorMessage] => Invalid key. [errorCode] => CT001 )
if( $data['result'] === false){
return false;
}
return true;
}
// 공통 CURL 처리
function request_curl($url){
// 공통헤더
$headers = array(
'X-Naver-Client-Id: '.NV_CLIENT_ID,
'X-Naver-Client-Secret: '.NV_CLIENT_SECRET
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 0);
if( count($headers) > 0){
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$data = curl_exec($ch);
$response = array();
// 통신 실패 처리
if (curl_error($ch)){
$response = array('rst'=>'fail','msg'=>'CURL Error('.curl_errno( $ch ).') '.curl_error($ch));
}
// 통신에 대한 성공이며, 실제 데이터에 대한 성공은 별도 처리 필요
else{
$response = array('rst'=>'success','data'=>$data);
}
curl_close($ch);
return $response;
}
?>
<?php
if( !empty($_POST['key']) && !empty($_POST['value'])){
$nvalid = request_nvalid($_POST['key'], $_POST['value']);
$resultMsg = '';
if( $nvalid !== true){ $resultMsg = '인증실패'; }
else{ $resultMsg = '인증성공'; }
?>
<h1>네이버 캡챠 이미지 인증 결과</h1>
<h3><?php echo $resultMsg ?></h3>
<p><a href="">다시 인증하기</a></p>
<?php
}else{
?>
<h1>네이버 캡챠 이미지 인증 요청</h1>
<form method="post">
<input type="hidden" name="key" value="<?php echo $nkey ?>">
<p><img src="<?php echo "data:image/jpeg;base64,".base64_encode($ncaptcha) ?>"></p>
<p><input type="text" name="value" placeholder="이미지 문자를 입력해주세요." style="width:200px"></p>
<p><input type="submit" value="전송"></p>
</form>
<?php } ?>
참고로 API 요청 그래프에 대한 정보는 아래 이미지와 같이 네이버 Developers > 내 애플리케이션 > API 통계에서 확인이 가능하다.