google로 이메일 인증을 구현해보자
IMAP 설정
이메일 클라이언트에서 Gmail을 사용할수 있게 IMAP 설정을 1단계로 구현한다
https://support.google.com/mail/answer/7126229?hl=ko&rd=3&visit_id=1-636281811566888160-3239280507#ts=1665018
보안 설정
보안설정이 높음으로 되어있으면 이메일이 정상적으로 보내지지 않으므로 보안설정을 낮음으로 바꿔준다
https://support.google.com/accounts/answer/6010255
그다음 Django에서 SMTP설정을 해주어야 하는데 방법은 다음과 같다
EMAIL = {
'EMAIL_BACKEND' : 'django.core.mail.backends.smtp.EmailBackend',
'EMAIL_USE_TLS' : True,
'EMAIL_PORT' : 587,
'EMAIL_HOST' : 'smtp.gmail.com',
'EMAIL_HOST_USER' : '본인 이메일주소@gmail.com',
'EMAIL_HOST_PASSWORD' : '이메일 주소 비밀번호',
'REDIRECT_PAGE' : 'http://10.58.5.40:3000/signin'
}
settings.py 파일에 있어도 되지만 남들에게 보이면 안되는 정보가 담겨있으므로 my_settings.py 와 같이 따로 파일을 만들어 두어 보관을 해야한다
그다음 settings.py에서 다음과 같은 코드를 추가한다
SITE_ID = 1
EMAIL_BACKEND = my_settings.EMAIL['EMAIL_BACKEND']
EMAIL_USE_TLS = my_settings.EMAIL['EMAIL_USE_TLS']
EMAIL_PORT = my_settings.EMAIL['EMAIL_PORT']
EMAIL_HOST = my_settings.EMAIL['EMAIL_HOST']
EMAIL_HOST_USER = my_settings.EMAIL['EMAIL_HOST_USER']
EMAIL_HOST_PASSWORD = my_settings.EMAIL['EMAIL_HOST_PASSWORD']
그다음 보낼 이메일 내용을 적을 text.py를 만들어 작성한다
def message(domain, uidb64, token):
return f"아래 링크를 클릭하면 회원가입 인증이 완료됩니다. \n\n 회원가입 링크 : http://{domain}/users/{uidb64}/{token}\n\n 감사합니다"
도메인 주소, 앱이름,토큰값으로 이루어진 URL주소를 만든다
다음으로 Users 모델클래스에 다음줄을 추가할건데 이는 is_active 값이 False라면 로그인이 되지 않게 하기위해 만들어준다
is_active = models.BooleanField(default=False)
또한 이메일 링크를 열었을때 동작할 기능을 view.py 에서 추가한다
class Activate(View):
def get(self, request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = Users.objects.get(pk=uid)
user_dic = jwt.decode(token,SECRET_KEY,algorithm='HS256')
if user.id == user_dic["user"]:
user.is_active = True
user.save()
return redirect("http://10.58.5.40:3000/signin")
return JsonResponse({'message':'auth fail'}, status=400)
except ValidationError:
return JsonResponse({'message':'type_error'}, status=400)
except KeyError:
return JsonResponse({'message':'INVALID_KEY'}, status=400)
그다음 회원가입을 할때 이메일을 보내는 기능을 view.py 내용을 추가한다
class SignUp(View):
def post(self, request):
data = json.loads(request.body)
try:
if re.search("[^a-zA-Z0-9]{6,12}$",data['user']):
return JsonResponse({'message':'id check'}, status=400)
elif re.search(r"[^A-Za-z0-9!@#$]{6,12}$",data['password']):
return JsonResponse({'message':'password check'}, status=400)
else:
try:
Users.objects.get(user=data['user'])
return JsonResponse({'message':'EXISTS ID'}, status=401)
except Users.DoesNotExist:
user = Users.objects.create(
user = data['user'],
email = data['email'],
password = bcrypt.hashpw(data['password'].encode('utf-8'),bcrypt.gensalt()).decode('utf-8'),
is_active = False
)
current_site = get_current_site(request)
domain = current_site.domain
uidb64 = urlsafe_base64_encode(force_bytes(user.pk))
token = jwt.encode({'user':user.id},SECRET_KEY,algorithm='HS256').decode('utf-8')
message_data = message(domain, uidb64, token)
mail_title = "이메일 인증을 완료해주세요"
mail_to = data['email']
email = EmailMessage(mail_title, message_data, to=[mail_to])
email.send()
return JsonResponse({'message':'SUCCESS'}, status=200)
except KeyError:
return JsonResponse({'message':'key wrong'}, status=402)
except TypeError:
return JsonResponse({'message':'type wrong'}, status=403)
except ValidationError:
return JsonResponse({'message':'VALIDATION_ERROR'}, status=404)
변경한 view.py에 대한 url을 추가한다
from django.urls import path
from .views import SignUp, SignIn, Activate
urlpatterns =[
...
path('activate/<str:uidb64>/<str:token>', Activate.as_view())
]
그다음 포스트맨을 이용해 회원가입하고
가입시 입력한 이메일을 보면 인증메일이 도착해있다
링크를 클릭하면 is_active 값이 True가 되어 로그인이 가능해진다