如何進行郵箱驗證
阿新 • • 發佈:2018-11-02
自己的專案中有繫結郵箱需求通常需要了解兩個點:一是要知道傳送郵件的方法,二是得知道郵件的啟用機制
以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)
序列化器:
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'})