Django调用send_mail触发WinError 10060超时错误求助
Django发送Gmail验证邮件时出现WinError 10060连接超时问题
错误日志
运行Daphne服务器调用send_mail()发送邮箱验证邮件时触发500错误,核心为连接超时:
PS> daphne -p 8000 Server.asgi:application 2024-06-26 11:36:00,313 INFO Starting server at tcp:port=8000:interface=127.0.0.1 2024-06-26 11:36:00,313 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras) 2024-06-26 11:36:00,313 INFO Configuring endpoint tcp:port=8000:interface=127.0.0.1 2024-06-26 11:36:00,314 INFO Listening on TCP address 127.0.0.1:8000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Internal Server Error: /Http/createUser Traceback (most recent call last): File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\asgiref\sync.py", line 534, in thread_handler raise exc_info[1] File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\core\handlers\exception.py", line 42, in inner response = await get_response(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\asgiref\sync.py", line 534, in thread_handler raise exc_info[1] File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async response = await wrapped_callback( ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\asgiref\sync.py", line 479, in __call__ ret: _R = await loop.run_in_executor( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TimeoutError: [WinError 10060] 连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败 2024-06-26 11:37:01,353 ERROR Internal Server Error: /Http/createUser Traceback (most recent call last): File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\asgiref\sync.py", line 534, in thread_handler raise exc_info[1] File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\core\handlers\exception.py", line 42, in inner response = await get_response(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\asgiref\sync.py", line 534, in thread_handler raise exc_info[1] File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\django\core\handlers\base.py", line 253, in _get_response_async response = await wrapped_callback( ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\asgiref\sync.py", line 479, in __call__ ret: _R = await loop.run_in_executor( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TimeoutError: [WinError 10060] 连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败 127.0.0.1:60554 - - [26/Jun/2024:11:37:01] "POST /Http/createUser" 500 50886
项目配置文件
Settings.py
INSTALLED_APPS = [ #'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'corsheaders', 'channels', 'rest_framework', 'Http', 'WebSocket', ] EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = 'myEmail' EMAIL_HOST_PASSWORD = 'myPassword' #DEFAULT_FROM_EMAIL = 'myEmail' # no-reply CORS_ALLOW_ALL_ORIGINS = True CORS_ALLOW_METHODS = [ 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', ] CORS_ALLOW_HEADERS = [ 'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ] # Is Gonna Change Manually FRONTEND_URL = '127.0.0.1:8000'
urls.py
from django.urls import path from . import views app_name = "Http" urlpatterns = [ path('createUser', views.create_user, name='CreateUser'), path('verifyEmail/', views.verify_email, name='VerifyEmail'), ]
views.py
from django.shortcuts import render, get_object_or_404 from django.views.decorators.csrf import csrf_exempt # No Csrf Prot from rest_framework.decorators import api_view from django.http import JsonResponse from . import models as DataBase from rest_framework import status # type: ignore from rest_framework.response import Response # type: ignore from rest_framework.views import APIView # type: ignore from .serializers import UserSerializer from .token_generator import emailVerificationToken @csrf_exempt @api_view(['POST']) def create_user(request): serializer = UserSerializer(data=request.data) if serializer.is_valid(): user = serializer.save() return Response({ 'message': 'User created successfully. Check your email for verification.', 'user_id': user.id }, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['GET']) def verify_email(request): token = request.GET.get('token') email = request.GET.get('email') user = get_object_or_404(DataBase.User, email=email) if emailVerificationToken.check_token(user, token): user.is_active = True user.save() return JsonResponse({'message': 'Email verified successfully.'}) else: return JsonResponse({'error': 'Invalid token or email.'}, status=400)
serializers.py
# serializers.py from rest_framework import serializers # type: ignore from django.contrib.auth import get_user_model from .models import ExtraClasses_EmailVerification from .token_generator import emailVerificationToken User = get_user_model() from django.core.mail import send_mail from django.urls import reverse from django.conf import settings class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'name', 'email', 'password', 'phoneNumber') def create(self, validated_data): user = User.objects.create_user(**validated_data) user.is_active = False user.save() token = emailVerificationToken.make_token(user) verification_record = ExtraClasses_EmailVerification.objects.create(user=user, token=token) verification_url = f"{settings.FRONTEND_URL}/Http/verifyEmail?token={token}&email={user.email}" print("\n\n\n\n\n\n\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n\n\n\n\n\n\n") send_mail( 'Verify your email', f'Click the link to verify your email: {verification_url}', settings.EMAIL_HOST_USER, [user.email], fail_silently=False, ) print("\n\n\n\n\n\n\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n\n\n\n\n\n\n") return user
models.py
from django.db import models from phonenumber_field.modelfields import PhoneNumberField # type: ignore from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager class ExtraClasses_CustomUserManager(BaseUserManager): def create_user(self, name, email, password=None, **extra_fields): if not email: raise ValueError('The Email field must be set') email = self.normalize_email(email) user = self.model(name=name, email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, name, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self.create_user(name, email, password, **extra_fields) class User(AbstractBaseUser, PermissionsMixin): """ Users That Use The Program """ profilePhoto = models.ImageField(upload_to='profileImages/', default='defaultImages/profileImage.png') name = models.CharField(max_length=32) friends = models.ManyToManyField('self') explanation = models.CharField(max_length=48) email = models.EmailField(unique=True) password = models.CharField(max_length=32) phoneNumber = PhoneNumberField(unique=True) date_joined = models.DateTimeField(auto_now_add=True) """ Django Authentication Parts """ is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=True) objects = ExtraClasses_CustomUserManager() USERNAME_FIELD = 'id' EMAIL_FIELD = 'email' def __str__(self) -> str: return self.name class ExtraClasses_EmailVerification(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) token = models.CharField(max_length=200) created_at = models.DateTimeField(auto_now_add=True) edited_at = models.DateTimeField(auto_now=True)
已排查内容
- 网络连接:使用
Test-NetConnection测试smtp.gmail.com 587端口成功,输出如下:Test-NetConnection -ComputerName smtp.gmail.com -Port 587 ComputerName : smtp.gmail.com RemoteAddress : -------------- RemotePort : 587 InterfaceAlias : Wi-Fi SourceAddress : -------------- TcpTestSucceeded : True - 排除路由器问题:其他电脑可正常解析smtp.gmail.com
- 关闭防火墙后问题仍存在
请求协助
需要排查并解决该邮件发送超时问题。
内容的提问来源于stack exchange,提问作者Omegames
相关产品推荐
相关产品推荐

