How could i achieve email functionality using drf as backeend and django to hit these apis.What i need how will user be confirm from django while using drf to send activation link.
1 Answer
At first, you need to add the code to send the verification email when you register.
from base64 import urlsafe_b64decode, urlsafe_b64encode
from django.contrib.auth.tokens import default_token_generator
from django.template.loader import render_to_string
from threading import Thread
class EmailRegisterView(APIView):
"""APIs for Email Registeration"""
permission_classes = [AllowAny]
def post(self, request):
"""Signup with Email"""
serializer = EmailRegisterSerializer(data=request.data)
if serializer.is_valid():
...
user.save()
// send verification link
cur_token = default_token_generator.make_token(user)
email = urlsafe_b64encode(str(user.email).encode('utf-8'))
# now send email
mail_subject = 'Email Confirmation'
message = render_to_string('emails/email_verification.html', {
'site_url': settings.SITE_URL,
'token': f'api/users/verify/{email.decode("utf-8")}/{cur_token}',
})
t = Thread(target=send_mail, args=(
mail_subject, message, settings.EMAIL_FROM_USER, to_email))
t.start()
return Response({
"success": True,
"user": MemberSerializer(user).data
}, status.HTTP_200_OK)
And you can add the confirmation view.
urlpatterns = [
...
path('verify/<str:email>/<str:email_token>',
verify_email, name="verify_token"),
...
]
Then the verify_email function verifies the token and redirects.
@api_view(['GET'])
@permission_classes([AllowAny])
def verify_email(request, email, email_token):
"""Verify Email"""
try:
target_link = settings.CLIENT_URL + "/account/result?type=email_verified"
if verify_token(email, email_token):
return redirect(target_link)
else:
return render(
request,
"emails/email_error.html",
{'success': False, 'link': target_link}
)
except BaseException:
pass
Here is the verify_token function.
def verify_token(email, email_token):
"""Return token verification result"""
try:
users = Member.objects.filter(
email=urlsafe_b64decode(email).decode("utf-8"))
for user in users:
valid = default_token_generator.check_token(user, email_token)
if valid:
user.is_verified = True
user.save()
return valid
except BaseException:
pass
return False