Contents
django 15 - allauth로 사용자 메일 인증받기
   2022년06월24일     5분정도면 다 읽어요     - Comments

[카카오 클라우드 스쿨] 사용자가 allauth를 통해 이메일 인증을 받도록 해 보자!

15. allauth: 사용자 메일 인증받기

15-1. 동작 과정

  • 클라이언트: 회원 가입시 이메일을 입력 받아야 함
  • 서버: 회원 정보를 DB에 저장함(단, 인증받지 않은 상태)
  • 회원 가입 과정
    1. 로그인을 하기 위해 이메일 인증이 필요하다
    2. 회원은 is_active=0인 상태로 가입한다 (로그인을 할 수 없는 상태로 가입됨)
    3. 이메일 인증이 완료되면 is_active=1로 변경된다


  • 메일 전송
    1. 파이썬 프로그램이 메일 서버에 접속해서 사용자에게 실제로 메일을 보냄(토큰값과 함께 전송)
      • 따라서 메일 서버가 필요함 (본인은 hotmail 서버를 사용할 것)
      • 토큰값: 사용자의 정보, 현재 시간 정보 등을 이용해서 랜덤 값으로 자동으로 생성됨
    2. 사용자가 메일을 통해 누른 링크(토큰값)이 서버 토큰값과 동일하면 is_active=1로 변경됨
      • is_active=1로 변경해주는 view를 호출하는 URL이 포함
    3. 시간 제한을 주어 인증처리/비처리 여부 결정


번외: 실무에서의 회원 탈퇴

  • 회원 탈퇴: 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. 방법 1: foreign key를 통해 어느 유저의 정보라는 것을 선언(추천하지 않음, 구현이 간단하지만 조인 관련 문제 발생 우려)
    2. 방법 2: AbstractUser 클래스를 상속받거나, AbstractBaseUser 클래스를 상속받을 수 있음
      1. AbstractUser: 조금만 커스터마이징 할 거면 선택
      2. 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
    • img_113.png
    • 회원 가입 완료
  • 터미널에 보낼 메일 내용이 나타남
    • img_114.png
  • 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 . 여기까지 변경 사항

  • 다시 회원가입
    • img_116.png
  • DB 에서 account_emailaddress 테이블 확인 시 링크를 누르면 이렇게 1로 인증됨
    • img_140.png



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 . 중간결과

  • 회원 가입시 인증 메일 발송됨
    • img_122.png
    • img_123.png

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 . 최종 결과

  • 이메일 발송 결과
    • img_126.png
  • 이메일 인증시 verified
    • img_158.png



(번외) django 관리자 계정 만들기

python manage.py createsuperuser
  • 이제 admin 사이트에서 로그인 가능!
  • 우리가 만든 user를 관리할 수 있도록 테이블을 추가해 보자

accounts/admin.py

from accounts.models import User
admin.site.register(User)
  • 결과
    • before img_124.png
    • after img_125.png


  • 그러면 이제 계정을 관리자 페이지에서 지울 수가 있음!