第1步:开启信箱SMTP服务,开启之后可以使用此邮箱给用户的邮箱发送验证邮件。
登录QQ邮箱—点击右上角“设置”—点击左下角“账号与安全”—点击左侧“安全设置”—找到“POP3/IMAP/SMTP/Exchange/CardDA服务"选项,按提示步骤开启SMTP服务,需要发送两个手机验证码。
第2步:在dev.py中设置邮件参数
# 指定邮件后端
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com' # 邮件主机
EMAIL_PORT = 465 # 邮件端口
EMAIL_USE_SSL = True
EMAIL_HOST_USER = '316620938@qq.com' # 授权的邮件,此外应为商城的官方邮箱
EMAIL_HOST_PASSWORD = 'wdggtnpzpaebbiea' # 上一步邮箱授权时生成的密码,而不是邮箱的注册登录密码
EMAIL_FROM = '小鱼商城<316620938@qq.com>' #
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
第3步:定义发送邮件的函数,在users应用下创建emails.py,并定义函数
import logging
from django.conf import settings
from django.core.mail import send_mail
logger = logging.getLogger('django')
def send_verification_email(to_email, verify_url):
"""发送邮件"""
subject = '小鱼商城邮箱验证'
html_message = '<p>尊敬的用户您好!</p>' \
'<p>感谢您使用小鱼商城。</p>' \
'<p>您的邮箱为:%s 。请单击此链接验证您的邮箱:</p>' \
'<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
try:
send_mail(subject, '', settings.EMAIL_FROM, [to_email], html_message=html_message)
except Exception as e:
logger.error(e)
第4步:在EmailView中补充发送验证邮箱的功能
class EmailView(LoginRequiredJSONMixin, View):
"""添加邮箱"""
def put(self, request):
"""实现添加邮箱逻辑"""
# 接收参数 body, 类型是bytes类型
json_str = request.body.decode()
json_dict = json.loads(json_str)
email = json_dict.get('email')
# print(email)
if not email: # 校验参数
return HttpResponseForbidden('缺少email参数')
if not re.match(
r'^[a-z0-9][\w\\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
return HttpResponseForbidden('参数email有误')
# 赋值email字段
try:
request.user.email = email
request.user.save()
except Exception as e:
logger.error(e)
return JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败'})
# 补充验证邮箱的功能
verify_url = '邮箱验证链接'
send_verification_email(to_email=email, verify_url=verify_url)
# 响应添加邮箱结果
return JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})
第5步:安装用户信息序列化的库
pip install itsdangerous==1.1.0
第6步:定义验证邮箱的链接部分的固定串和有效期,在dev.py中
# 邮箱验证链接的固定字符串
EMAIL_VERIFY_URL = 'http://127.0.0.1:8000/emails/verification/'
# 邮箱验证链接的有效期,24小时
VERIFY_EMAIL_TOKEN_EXPIRES = 60 * 60 * 24
第7步:在users应用下utils.py中定义生成邮箱验证url的函数和反序列化的函数。
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData
def check_verify_email_token(token):
"""反序列化token
:param token:序列化后的token
:return:user"""
serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
try:
data = serializer.loads(token)
except BadData:
return None
else:
user_id = data.get('user_id')
email = data.get('email')
try:
user = User.objects.get(id=user_id, email=email)
except User.DoesNotExist:
return None
else:
return user
def generate_verify_email_url(user):
"""生成邮箱验证url"""
serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
data = {'user_id': user.id, 'email': user.email}
token = serializer.dumps(data).decode()
verify_url = settings.EMAIL_VERIFY_URL + '?token=' + token
return verify_url
在users应用下创建constants.py,用于定义常量
# 邮件验证链接有效期:一天
VERIFY_EMAIL_TOKEN_EXPIRES = 60 * 60 * 24
# 用户地址上限
USER_ADDRESS_COUNTS_LIMIT = 20
# 显示我的订单数量
ORDERS_LIST_LIMIT = 5
第8步:在users应用views.py中使用generate_verify_email_url()
函数,将原来的字符串换在函数
# verify_url = '邮箱验证链接'
verify_url = generate_verify_email_url(request.user)
第9步:views.py中定义验证邮箱的类视图
class VerifyEmailView(View):
"""验证邮箱"""
def get(self, request):
# 从请求中取到token
token = request.GET.get('token')
if not token:
return HttpResponseForbidden('缺少token')
user = check_verify_email_token(token) # 从token中提取信息
try:
user.email_active = True
user.save()
except Exception as e:
logger.error(e)
return HttpResponseForbidden('邮箱验证失败')
return redirect(reverse('users:info'))
第10步:定义路由
path('emails/verification/', views.VerifyEmailView.as_view()),