一.注冊郵箱
可以使用QQ,新浪,163等等,每個郵箱端口可能不一樣,這里以新浪為例,登錄后修改設置中開啟POP/SMTP服務如下:
二.setting中的配置
相應參數可以參考官網,常用如下:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.sina.com' EMAIL_PORT = 25 #郵箱用戶名 EMAIL_HOST_USER = '***@sina.com' #郵箱密碼 EMAIL_HOST_PASSWORD = 'password' EMAIL_USE_TLS = False #一般和用戶名一樣 EMAIL_FROM = '發送者'
注:端口可能不能用,如我遇到的問題是在本地測試能發送郵件,部署到服務器(阿里雲centos7.0)上則總是超時,很頭疼,查詢了相關資料,如下:
服務器25端口被大量垃圾郵件充斥,嚴重影響廣大用戶正常使用。為了共同維護良好的網絡環境,阿里雲服務器不再提供25端口郵件服務,阿里雲企業郵箱將80端口重定向到了25端,與直接調用25端的發信方式沒有區別。如果是阿里雲的郵箱,需要使用 80 端口發送郵件。然后需要再郵件設置里,把發送端口改為 465 或 80 端口進行發送,其他郵箱建議嘗試使用465加密端口發送郵件,或與郵件發信提供商咨詢是否還有其他smtp發信端口。
於是我嘗試用465端口,還是不行,最后嘗試587端口成功。
三.編寫發送的代碼
代碼比較簡單,可以根據自己的需要定制
# _*_ encoding:utf-8 _*_ __author__ = 'LYQ' __data__ = '2018/8/2 20:06' from random import Random from django.core.mail import send_mail from News_Contrl.settings import EMAIL_FROM def random_str(randomlength=8): str = '' chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789' length = len(chars) - 1 random = Random() for i in range(randomlength): str += chars[random.randint(0, length)] return str def send_register_email(email, send_type='register'): code = random_str(4) if send_type == 'register': email_title = 'CINS爬蟲監控系統注冊' email_body = '您的驗證碼為:{0},五分鍾內注冊有效,否則請從新獲取'.format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: return code,send_status elif send_type == 'forget': email_title = 'CINS爬蟲監控系統密碼找回' email_body = '請點擊下面的鏈接找回你的賬號:http://127.0.0.1:8000/reset/{0}'.format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: return code, send_status, send_type elif send_type == 'update_email': email_title = 'CINS爬蟲監控系統郵箱修改' email_body = '您的郵箱驗證碼為:{0}'.format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: return code, send_status, send_type if __name__ == "__main__": send_register_email("1508414512@qq.com")
四.序列化
我這里是用的項目是前后端分離的(drf),如果是用的Django,則可以用表單驗證(Form,ModelForm等)。
class EmailSerializer(serializers.Serializer): ''' 注冊和郵箱驗證碼序列化 ''' email = serializers.CharField(max_length=30, min_length=5) def validate_email(self, email): ''' 驗證郵箱 ''' # 驗證郵箱是否合法 if not re.match(REGEX_EMAIL, email): raise serializers.ValidationError('郵箱非法') # 郵箱是否注冊 if User.objects.filter(email=email).count(): raise serializers.ValidationError('用戶已經存在') on_minute_ago = datetime.now() - timedelta(hours=0, minutes=1, seconds=0) if EmailVeriyRecord.objects.filter(send_time__gt=on_minute_ago, email=email, send_type='register'): raise serializers.ValidationError('距離上一次發送未超過60秒') return email
五.發送郵箱接口
class EmailCodeViewset(mixins.CreateModelMixin, viewsets.GenericViewSet): """ 郵箱驗證碼接口 create: 驗證碼發送至郵箱 """ serializer_class = EmailSerializer def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) email = serializer.validated_data['email'] code, email_status = send_register_email(email) if not email_status: return Response({'email': "驗證發送失敗"}, status=status.HTTP_400_BAD_REQUEST) else: email_record = EmailVeriyRecord() email_record.code = code email_record.email = email email_record.send_type = "register" email_record.save() return Response({'email': email}, status=status.HTTP_201_CREATED) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
六.心得體會
看似不難的東西,結果因為端口查了一下午的資料,嘿呀,都是眼淚花花啊,希望能找到一起交流學習的小伙伴,拒絕利益交友,只是希望能一同討論共同進步,如果你感興趣,請加QQ:1508414512,本人很友好熱情,積極向上,做事認真負責,呃呃,詞窮,反正不止這點優點。