如何進行郵箱驗證

自己的項目中有綁定郵箱需求通常需要了解兩個點:一是要知道發送郵件的方法,二是得知道郵件的激活機制
以django框架中郵箱驗證爲例

1:綁定郵箱和發送郵件,首先得給自己定義好的表裏的email字段添加一個有效的郵箱,然後使用SMTP服務器給此郵箱發送郵件

django發送郵件的方法:Django中內置了郵件發送功能,被定義在django.core.mail模塊中。發送郵件需要使用SMTP服務器,常用的免費服務器有:163、126、QQ,下面以163郵件爲例
步驟1):註冊一個郵箱,在郵箱管理界面設置一下,使其成爲服務器,拿到自己設置的授權密碼
步驟2):在Django配置文件中,設置郵箱的配置信息

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
#發送郵件的郵箱
EMAIL_HOST_USER = '[email protected]'
#客戶端授權密碼
EMAIL_HOST_PASSWORD = 'demo123'
#收件人看到的發件人信息
EMAIL_FROM = '郵件測試<[email protected]>'

步驟3):使用Django提供的模塊發送郵件
在django.core.mail模塊提供了send_mail來發送郵件。

send_mail(subject, message, from_email, recipient_list,html_message=None)
# 例如
send_mail('註冊測試','',settings.EMAIL_FROM, ['[email protected]'], html_message='<a>hello</a>')
  • subject 郵件標題
  • message 普通郵件正文, 普通字符串
  • from_email 發件人
  • recipient_list 收件人列表
  • html_message 多媒體郵件正文,可以是html字符串
    步驟4):保存郵箱,發送郵件。寫一個接口,用於修改用戶email字段值,可設置認證用戶然後改寫get_object
    序列化器:
class EmailSerializer(serializers.ModelSerializer):
    """
    郵箱序列化器
    """
    class Meta:
        model = User
        fields = ('id', 'email')
        extra_kwargs = {
            'email': {
                'required': True
            }
        }

    def update(self, instance, validated_data):
        instance.email = validated_data['email']
        instance.save()
        return instance

視圖:

from rest_framework.generics import UpdateAPIView
from .serializers import EmailSerializer

class EmailView(UpdateAPIView):
    """
    保存用戶郵箱
    """
    permission_classes = [IsAuthenticated]
    serializer_class = EmailSerializer

    def get_object(self, *args, **kwargs):
        return self.request.user

最後配置路由
2:驗證郵箱,爲了能區分是哪個用戶在進行郵箱驗證,需要在鏈接中包含用戶和郵箱的識別信息,如user_id和email數據,但是基於安全性的考慮,不能將這兩個數據直接暴露在郵件鏈接中,而是需要進行隱藏和簽名處理,這是可使用itsdangerous包中的dumps和loads方法來進行加密和解密。
步驟1):生成發送驗證的url

from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer
class User(models.Model)
	    serializer = TJWSSerializer(SECRET_KEY, expires_in=EXPIRES_TIME)
        data = {'user_id': self.id, 'email': self.email}
        token = serializer.dumps(data).decode()  # 加密後是bytes類型,要轉爲字符串
        verify_url = 'http://demo:8080/success_verify_email.html?token=' + token
        return verify_url

拿到url後拼接html_message

html_message =  '<p>尊敬的用戶您好!</p>' \
                '<p>您的郵箱爲:%s 。請點擊此鏈接激活您的郵箱:</p>' \
                '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
    

然後調用自帶的send_mail方法,想當前用戶發送郵件

send_mail(subject, "", settings.EMAIL_FROM, [to_email], html_message=html_message)

步驟2):用戶在自己收到的郵件中點擊鏈接,服務器接收請求,驗證token
在users/models.py中,爲User模型類定義驗證token的方法

from itsdangerous import BadData

    @staticmethod
    def check_verify_email_token(token):
        """
        檢查驗證郵件的token
        """
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
        try:
            data = serializer.loads(token)
        except BadData:
            return None
        else:
            email = data.get('email')
            user_id = data.get('user_id')
            try:
                user = User.objects.get(id=user_id, email=email)
            except User.DoesNotExist:
                return None
            else:
                return user

新建視圖對序列化器和模型類進行處理

class VerifyEmailView(APIView):
    """
    郵箱驗證
    """
    def get(self, request):
        # 獲取token
        token = request.query_params.get('token')
        if not token:
            return Response({'message': '缺少token'}, status=status.HTTP_400_BAD_REQUEST)

        # 驗證token
        user = User.check_verify_email_token(token)
        if user is None:
            return Response({'message': '鏈接信息無效'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            user.email_active = True
            user.save()
            return Response({'message': 'OK'})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章