২৩.৩ : রেজিস্ট্রেশন ইমেইল সেন্ড করা

আজকে আসো আমরা আমাদের ইউজার রেজিষ্টেশন টাইম এ যে ইমেইল দিয়েছিল সেই মেইল এ তাকে মেইল পাঠাবো এবং এডমিন প্যানেল এর Active অপশন টা অফ করে দিবো যাতে ইমেইল ভারিফাই না করা অব্দি সে ওয়েবসাইট এ লগইন করতে না পারে।

সো যেহেতু ইমেইল সেন্ড করতে হবে সো আগের সেই ব্যাংক ম্যানেজমেন্ট প্রজেক্ট এর মত করে environment ভ্যারিয়েবল দিয়ে ইমেইল সেটাপ করে ফেলবো। আর সেই সাথে gmail এর সেই অ্যাপ তৈরি করতে হবে, যেটা তুমি তোমার মত নাম দিয়ে তৈরি করবে, মডিউল এ দেখানো কোনো নাম, পাসওয়ার্ড ইউজ করবে না।

Google Account → Security → 2 Step Verification → App Password তৈরি করবে।

তো এখন আসো যে ইউজার রেজিস্ট্রেশন করবে তার একাউন্ট টা অ্যাক্টিভ করবো না, সেজন্যে নিচের কোড টা খেয়াল করে দেখো যে সে রেজিস্ট্রেশন করার ফরম ফিল আপ করার সাথে সাথে আমরা তার একাউন্ট ক্যাপচার করে is_active কে False করে দিলাম তাইলে সে আর ওয়েবসাইট এ লগইন করতে পারবে না।

সো ভিউ তে চলে আসি এখন সেখানে প্রত্যেক রেজিস্ট্রেশন ফরম ফিল আপ করা ইউজার এর জন্যে আমরা ইউনিক টোকেন বা টিকেট বানাবো। সেটার জন্যে django এর বিল্ট ইন টোকেন জেনারেটর কে ইউজ করবো আর সেটার make_token কল করে সেখানে সেই ইউজার কে বসিয়ে দিবো। তাইলে তার জন্যে টোকেন তৈরি হয়ে যাবে সেই সাথে এই ভেরিফিকেশন লিংক কে আরো স্ট্রং করার জন্যে আমরা uid অর্থাৎ ইউনিক একটা আইডি বানাবো কারণ টা হচ্ছে token তো জাস্ট একটা টিকেট তাই না। মুভি দেখার পর সবাই যেমন টিকেট ছিঁড়ে ফেলে ঠিক তেমনি এই টোকেন টাও একটা টেম্পোরারি মুভি টিকেট এর মত । সো আমরা ইউজার এর প্রাইমারি কি দিয়ে একটা আইডি বানাবো যেটাকে encode করবো অর্থাৎ কেউ জানবে না এই আইডি এর পিছনে কি আছে পরে যখন ওই ইউজার কে তার মেইল ভেরিফাই করতে যাবে আর লিংক এ ক্লিক করবে তখনি তার সেই ইউনিক আইডি কে ক্যাপচার করে, decode আমরা ধরে ফেলবো এটা কোন ইউজার।

এখন এই token আর uid দিয়ে আমরা একটা লিংক বানাবো যেই লিংক এ ক্লিক করলেই ইউজার ভেরিফাইড হবে আর তার এডমিন প্যানেল এর Active অপশন টা ট্রু হয়ে যাবে।

আর ইমেইল সেন্ড করার জন্যে আগে যেমন আমরা render_to_string ইউজ করতাম html কে স্ট্রিং এ কনভার্ট করার জন্যে সেটাই ইউজ করবো আর EmailMultiAlternatives ফাংশন ইউজ করে ইউজার কে সেন্ড করবো।

settings.py

import environ
env = environ.Env()
environ.Env.read_env()

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = env("EMAIL")
EMAIL_HOST_PASSWORD = env("EMAIL_PASSWORD")

patient/views.py

from django.shortcuts import render
from rest_framework import viewsets
from . import models
from . import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from rest_framework.authtoken.models import Token
# for sending email
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.shortcuts import redirect


class PatientViewset(viewsets.ModelViewSet):
    queryset = models.Patient.objects.all()
    serializer_class = serializers.PatientSerializer

class UserRegistrationApiView(APIView):
    serializer_class = serializers.RegistrationSerializer
    
    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        
        if serializer.is_valid():
            user = serializer.save()
            print(user)
            token = default_token_generator.make_token(user)
            print("token ", token)
            uid = urlsafe_base64_encode(force_bytes(user.pk))
            print("uid ", uid)
            confirm_link = f"http://127.0.0.1:8000/patient/active/{uid}/{token}"
            email_subject = "Confirm Your Email"
            email_body = render_to_string('confirm_email.html', {'confirm_link' : confirm_link})
            
            email = EmailMultiAlternatives(email_subject , '', to=[user.email])
            email.attach_alternative(email_body, "text/html")
            email.send()
            return Response("Check your mail for confirmation")
        return Response(serializer.errors)

patient/urls.py

from rest_framework.routers import DefaultRouter
from django.urls import path, include
from . import views
router = DefaultRouter() # amader router

router.register('list', views.PatientViewset) # router er antena
urlpatterns = [
    path('', include(router.urls)),
    path('register/', views.UserRegistrationApiView.as_view(), name='register'),
]

Last updated