django 15 - allauth로 사용자 메일 인증받기
[카카오 클라우드 스쿨] 사용자가 allauth를 통해 이메일 인증을 받도록 해 보자!
15. allauth: 사용자 메일 인증받기
15-1. 동작 과정
- 클라이언트: 회원 가입시 이메일을 입력 받아야 함
- 서버: 회원 정보를 DB에 저장함(단, 인증받지 않은 상태)
- 회원 가입 과정
- 로그인을 하기 위해 이메일 인증이 필요하다
- 회원은 is_active=0인 상태로 가입한다 (로그인을 할 수 없는 상태로 가입됨)
- 이메일 인증이 완료되면 is_active=1로 변경된다
- 메일 전송
- 파이썬 프로그램이 메일 서버에 접속해서 사용자에게 실제로 메일을 보냄(토큰값과 함께 전송)
- 따라서 메일 서버가 필요함 (본인은 hotmail 서버를 사용할 것)
- 토큰값: 사용자의 정보, 현재 시간 정보 등을 이용해서 랜덤 값으로 자동으로 생성됨
- 사용자가 메일을 통해 누른 링크(토큰값)이 서버 토큰값과 동일하면 is_active=1로 변경됨
- is_active=1로 변경해주는 view를 호출하는 URL이 포함
- 시간 제한을 주어 인증처리/비처리 여부 결정
- 파이썬 프로그램이 메일 서버에 접속해서 사용자에게 실제로 메일을 보냄(토큰값과 함께 전송)
번외: 실무에서의 회원 탈퇴
- 회원 탈퇴: DB에서 지우지 않는 경우가 있음
- 안남겨두면 문제가 터질 수 있으니(법적으로) 보통 탈퇴하면 일정 기간동안 DB에 남겨둔다
- 휴면계정: active 상태를 0으로 변경하여 휴면 계정으로 만듦
- 그러면 휴면 계정을 제외한 유저만 조회해서 더욱 빠르게 쿼리(로그인) 가능
15-2. AbstractUser를 상속받아 메일 보내는 모델 구현하기
1 . 모델을 직접 만들지 않고 id-auth(로그인 관련 쉽게 구현해 둔 모듈) 사용 에정
pip install django-allauth
2 . 새 프로젝트에서 앱 생성하기
python manage.py startapp accounts
3 . settings.py 구성
- 앱을 다음과 같이 추가함
# 사용자 관리 앱
'accounts',
'allauth',
'allauth.account',
'django.contrib.sites',
- 또한 앱 하단부에 다음을 작성함
# 헷갈리면 우리가 만든 모델을 쓰라 (model/User())
AUTH_USER_MODEL = 'accounts.User'
# # # 이메일 서버용 # # # # # # # # # # # # #
# 여러 사이트를 하나의 사이트에서 관리할 수 있음
SITE_ID = 1
# 인증 백엔드 추가
AUTHENTICATION_BACKENDS = {
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
}
2 . accounts/models 에 상속받는 모델 생성
- 유저모델 확장 방법
- 방법 1: foreign key를 통해 어느 유저의 정보라는 것을 선언(추천하지 않음, 구현이 간단하지만 조인 관련 문제 발생 우려)
- 방법 2: AbstractUser 클래스를 상속받거나, AbstractBaseUser 클래스를 상속받을 수 있음
- AbstractUser: 조금만 커스터마이징 할 거면 선택
- AbstractBaseUser: 모든 것을 구성 가능, 모델 인증방식 모두 커스터마이징(직접 구현)
- 우린 AbstractUser를 통째로 상속받는 User모델만들기
models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
# 끝이냐구요? 네! 그냥 상속받은것 뿐
3 . URL도 내장 URL 사용할 예정
- allauth.urls 내부의 다양한 url을 사용할 수 있다
urls.py
from django.urls import path, include
urlpatterns = {
path('accounts/', include('allauth.urls')),
}
4 . 현재까지의 동작 과정
- allauth 에서 만든 URL
- 회원 가입 완료
- 터미널에 보낼 메일 내용이 나타남
- account_emailaddress 를 확인하면 현재 설정은 이메일 인증 받지 않아도 회원 자격(1)이 있음
5 . 이제 이메일 인증 받아야만 회원 자격을 부여해 보자
settings.py
# 유저네임으로 할거냐, 이메일로 할거냐 - 우리는 이메일로만 회원가입
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
# 기본적으로 이메일 인증을 안하면 활동 불가/ none:이메일 인증 안함 / optional:기본값, 인증 선택 가능
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
# get으로 컨펌할건지 이를 설정 해줌(사용자가 링크를 클릭헤서 들어오면 get방식)
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
5 . 여기까지 변경 사항
- 다시 회원가입
- DB 에서 account_emailaddress 테이블 확인 시 링크를 누르면 이렇게 1로 인증됨
15-3. 메일 서버를 통해 실제로 인증 받아보기
1 . 인증 메일 실제로 받기
- 이제 hotmail 메일 서버에서 메일이 가도록 해야 함
- 서버가 클라이언트로 쏴 주는 프로토콜: SMTP
- 클라이언트가 서버로부터 가져오는 프로토콜: POP3, IMAP
서버 이름: smtp.office365.com
포트: 587
암호화 방법: STARTTLS
2 . 따라서 이를 바탕으로 config.py에 다음과 같이 더 추가한다
# 이메일 백엔드 추가
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.office365.com' # 메일 호스트 서버
EMAIL_PORT = '587' # 메일과 통신하는 포트
EMAIL_HOST_USER = 'clolteam@hotmail.com' # 발신할 이메일
EMAIL_HOST_PASSWORD = 'password' # 발신할 이메일의 비밀번호
EMAIL_USE_TLS = True # TLS 보안 방법
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER #
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1 # 링크 유효기간
ACCOUNT_EMAIL_SUBJECT_PREFIX = '[회원 가입을 완료해 주세요]' # 제목 앞에 붙일 메시지
3 . 중간결과
- 회원 가입시 인증 메일 발송됨
4 . 메일 보내는 내용 변경하기
- 메일 내용은 우리가 원하는 내용(txt, html)으로 바꿀 수 있고, 템플릿 언어를 쓸 수 있음
- 정해진 위치에 넣으면 됨
- (template/)account/email/email_confirmation_signup_subject.txt
- (template/)account/email/email_confirmation_signup_message.txt
- account/email/email_confirmation_signup_message.html
- account/email/email_confirmation_signup_subject.html
회원님, 이메일 인증을 해 주세요
5 . 최종 결과
- 이메일 발송 결과
- 이메일 인증시 verified
(번외) django 관리자 계정 만들기
python manage.py createsuperuser
- 이제 admin 사이트에서 로그인 가능!
- 우리가 만든 user를 관리할 수 있도록 테이블을 추가해 보자
accounts/admin.py
from accounts.models import User
admin.site.register(User)
- 결과
- before
- after
- 그러면 이제 계정을 관리자 페이지에서 지울 수가 있음!