본문 바로가기

스터디-ing/Programming

[Javascript] Google reCAPTCHA

회원가입이나 로그인 기능을 구현하면서 보안 측면에서 간단하면서 확실한 방식이 있어 공유하려한다.

사실 누구나 한번쯤 로그인을 하면서 봤던 기능일 수 있다.
스팸이나 웹사이트 악용, 반복 로그인 시도를 보호할 수 있는 간단한 하면서 쉬운 유틸!
로그인 시도를 여러번 하면서 실패하면 보안문자를 입력하도록 하는 기능인 Google APIreCaptcha 이다

 

reCaptcha는 1, 2, 3버전이 있는데
v1 버전은 아래처럼 보안문자를 입력하는 방식이고

reCaptcha v1

 

이번에 사용한 v2은 `로봇이 아님`을 체크하는 `체크박스` + `이미지` 선택 하는 방식이다.

reCaptcha v2

특이한건 지금까지 확인된 바로는 크롬에서는 로봇아님 체크만 뜨는 반면
**그 외 브라우져에서는 이미지 선택까지 나온다.(참고!)**

 

 

v3 버전은 `이용자의 특정 행동 없이 구글이 봇 여부를 판단해 점수를 부여하는 형태` 라고 정의되어 있는데 아래의 점부 부여 기준을 따른다고 한다.

  • 페이지 로드: 유저가 웹 페이지를 로드할 때, 스크립트가 실행되어 사용자의 브라우저에서 실행된다.
  • 행동 분석: 유저가 웹 페이지를 탐색하는 동안, 행동을 실시간으로 분석한다. 분석에 포함되는 행동에는 마우스 이동, 클릭 패턴, 키보드 입력 등 여러가지가 포함된다.
  • 신뢰 점수 계산: 이를 바탕으로 유저 행동을 분석 후 신뢰 점수를 계싼하는데, 이 점수는 해당 유저가 로봇일 확률을 나타내는 지표이다. 점수는 0~1.0 사이고, 0.0에 가꾸울 수록 봇일 가능성이 매우 높은 것으로 판단하고 반대로 1.0에 가꾸울 수록 사람일 가능성이 높다는 뜻이다.
  • 웹사이트 동작 결정: reCaptcha API를 통해 신뢰 점수를 받아오고, 이 점수를 기반으로 로봇으로 의심되는 유저에 대한 추가적인 보안 조취를 취할지를 판단해서 결정한다.

 

여기까지는 버전에 따른 차이점을 확인해 보았다.

 

다음은 실제로 reCaptcha를 사용하는 방법에 대해 알아보자!

 

[reCaptcha API key 발급]

reCaptcha를 적용하기 위해선 api key를 발급받아야 한다.
아래 구글 reCAPTCHA 사이트로 접속해서
Linkhttps://www.google.com/recaptcha/intro/index.html

 

`Get Started with Enterprise` 클릭 후

 

원하는 프로젝트 명을 적고 `시작하기` 클릭

조금 기다리면… 프로젝트가 생성되고

 

바로 키 만들기 화면으로 전환된다.

여기서 ``를 생성하면 reCAPTCHA 붙이기 준비 끝!

발급받은 `api key`를 `환경변수`나 `숨김파일`에 저장 후 프로그램에서 불러오도록 준비함!

token을 발급받기 위한 인증(보안 기능 답..다ㅎ)

 

프론트에서 체크박스와 이미지를 모두 선택하고 나면 token을 발급해주는데
이를 api키와 함께 reCaptcha로 인증요청을 하면 인증되는 방식이다.

 

아래는 인증하는 코드 예시로 참고할 분들은 참고하기를~~!

 

module.exports = {
	googleRecaptchaUrl : (token)=>{
	    return `https://www.google.com/recaptcha/api/siteverify?secret=${GOOGLE_RECAPTCH_SECRET_KEY}&response=${token}`;
	}
}

async function googleRecaptchCheck(token){
    let result = {
        status: false,
        error: null,
    };
    try{
        let axiosData = {
            url: googleRecaptchaUrl(token),
            method: 'post',
            data: {},
            headers : {'Content-Type': 'application/json'}
        }
        let { data } = await apiCall(axiosData);
    
        // 알맞지 않은 api key나 token을 전송했을 때 응답
        /**
            recaptcha data , result:  {
                success: false,
                'error-codes': [ 'invalid-input-response' ],
                payload: {}
            }
         */
        // 인증 성공
        if(data.success){
            result.status = true;
        }else{
            result.error = data['error-codes'];
        }
    }catch(err){
        logError('googleRecaptchCheck catch err', err.toString());
    }finally{
        return result;
    }
}