이 세상엔 무서운 사람들이 많다. 전 세계를 돌아다니며 어딘가를 뚫고 들어오려는 동유럽 친구들을 두고 하는 말이다. 자신의 블로그나 웹페이지가 있다면 네이버나 구글 애널리틱스 등을 통해서 한 번 지켜보면 분명히 바다 넘어의 누군가가 우리를 지켜보고 있다는 것을 알 수 있을 것이다. 이런 저런 연유로 이번에는 django 웹앱에서 구글 recaptcha를 넣어서 기계가 아닌 진정한 사람만이 회원가입을 할 수 있도록 하려한다.

이게 뭔지 모르는 사람을 위해 CAPTCHA의 위키 설명을 첨부한다.

CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart, 완전 자동화된 사람과 컴퓨터 판별,캡차)는 HIP(Human Interaction Proof) 기술의 일종으로, 어떠한 사용자가 실제 사람인지 컴퓨터 프로그램인지를 구별하기 위해 사용되는 방법이다. 사람은 구별할 수 있지만 컴퓨터는 구별하기 힘들게 의도적으로 비틀거나 덧칠한 그림을 주고 그 그림에 쓰여 있는 내용을 물어보는 방법이 자주 사용된다. 이것은 기존의 텍스트와 이미지를 일그러뜨린 형태로 변형한 후 인식 대상이 변형된 이미지로부터 기존 이미지를 도출해 낼 수 있는지를 확인하는 방식의 테스트이다. 컴퓨터 프로그램이 변형시킨 이미지는 사람이 쉽게 인식 할 수 있지만 컴퓨터 프로그램은 변형된 이미지를 인식하지 못하므로 테스트를 통과하지 못한다면 테스트 대상이 사람이 아님을 판정할 수 있다. 흔히 웹사이트 회원가입을 할 때 뜨는 자동가입방지 프로그램 같은 곳에 쓰인다.

그리고 실제로 구글 recaptcha가 제공하는 서비스는 다음과 같은 우리에게 익숙한 것이다.

구글 recaptcha 페이지에서 이것을 어떻게 심고 사용하는 지에 대해서 나와있다. 실제로 그 지침을 따라서 잘 만들면 되지만 이미 잘 돌아가는 완성품이 있다면 마다할 이유는 없지 않을까. 그래서 여기서는 recaptcha를 django에서 구현한 django-recaptcha를 쓸 것이고, django-allauth가 제공하는 회원가입 기능에 사용할 것이다. 다만 django-allauth는 문제없이 잘 쓰고 있는 상태를 가정하고 그 위에다가 django-recaptcha를 합쳐 올리는 방법에 대해서만 써본다. django-allauth는 회원관리와 이메일 인증, 소셜 로그인 등을 하나로 묶은 매우 훌륭한 모듈인데 나중에 시간이 된다면 정리하고 싶다.

코딩에 대한 이야기를 하기 전에 구글 recaptcha에 가입하여 사이트를 등록하고 공개 키와 비밀 키를 받아놓아야 한다. 그래야 내 사이트에 이것을 심을 수 있다.

이제 설치를 하자. (virtualenv는 잘 쓰고 계실 것이라 생각한다)

pip install django-recaptcha

그리고 습관처럼 django 프로젝트의 settings.pyINSTALLED_APPS 'captcha' 를 넣는 것을 잊지말자. 또한 django-recaptcha의 옵션들을 다음과 같이 입력해준다.

INSTALLED_APPS = ( 'django.contrib.admin' 등의 기본 목록들, 본인의 앱들,

    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',

    'captcha',
)

... 중략 ...

RECAPTCHA_PUBLIC_KEY = '본인의 PUBLIC KEY'
RECAPTCHA_PRIVATE_KEY = '본인의 SECRET KEY'
RECAPTCHA_USE_SSL = True
NOCAPTCHA = True or False 취향따라 고르세요

NOCAPTCHA = True이면 요즘 디자인의 세련된 그림 맞추기가 나오고, False이면 구식 숫자 맞추기가 나온다. 이제 우리는 recaptcha를 쓸 준비가 끝났다. 이제 원하는 form에 넣어주면 된다.

from django import forms
from captcha.fields import ReCaptchaField

class SomeForm( forms.Form ):
    captcha = ReCaptchaField( )

끝이다. 그 이후의 구글에서 이야기하는 인증 절차는 내가 신경쓸 필요없이 이미 작동되는 단계로 올라온 것이다. 편하다.

이제 좀 더 나아가 django-allauth를 통해 이미 존재하는 회원가입 페이지에 넣으려고 한다. 위에서 recaptcha를 쓰려면 django form에 필드를 넣어야 했으므로 여기서는 allauth의 회원가입 form을 갖고와 덮어 쓰고 그 form을 쓸 것이라고 django와 allauth에게 잘 알려주면 된다. 또한 attrs 속성에 다음과 같이 한글 모드를 지정할 수도 있다.

# myapp/forms.py
from allauth.account.forms import SignupForm

from captcha.fields import ReCaptchaField

class MySignupForm( SignupForm ):
    captcha = ReCaptchaField( attrs={ 'lang': 'ko' } )

# settings.py에 추가
ACCOUNT_FORMS = { 'signup': 'myapp.forms.MySignupForm' }

이제 마지막 단계로 기존에 잘 쓰고 있던 회원가입 페이지에 조금만 관련 내용을 추가해주면 된다. 위에 지정한 MySignupForm을 어떻게 쓰느냐에 따라

1. {{ form }}을 통째로 쓰는 경우: 그냥 잘 쓰시면 됩니다><

2. {{ form.field }}를 따로따로 쓰는 경우: captcha 필드도 {{ form.captcha }}로 추가해줘야 할 것이다. 또한 {{ form.captcha.errors }}를 통해 잘못 입력했을 경우의 에러 메시지도 표시할 수 있다.

이리도 허접하게 끝.



참조

Google reCaptcha
https://google.com/recaptcha

Wiki for CAPTCHA
https://ko.wikipedia.org/wiki/CAPTCHA

django-recaptcha
https://github.com/praekelt/django-recaptcha

django-allauth와 함께 recaptcha 쓰는 방법
http://stackoverflow.com/questions/22665211/is-there-any-solutions-to-add-captcha-to-django-allauth