共计 5352 个字符,预计需要花费 14 分钟才能阅读完成。
增加邮箱后端逻辑
1. 增加邮箱接口设计和定义
1. 申请形式
选项 | 计划 |
---|---|
申请办法 | PUT |
申请地址 | /emails/ |
2. 申请参数
参数名 | 类型 | 是否必传 | 阐明 |
---|---|---|---|
string | 是 | 邮箱 |
3. 响应后果:JSON
字段 | 阐明 |
---|---|
code | 状态码 |
errmsg | 错误信息 |
2. 增加邮箱后端逻辑实现
class EmailView(View):
"""增加邮箱"""
def put(self, request):
"""实现增加邮箱逻辑"""
# 接管参数
json_dict = json.loads(request.body.decode())
email = json_dict.get('email')
# 校验参数
if not email:
return http.HttpResponseForbidden('短少 email 参数')
if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
return http.HttpResponseForbidden('参数 email 有误')
# 赋值 email 字段
try:
request.user.email = email
request.user.save()
except Exception as e:
logger.error(e)
return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '增加邮箱失败'})
# 响应增加邮箱后果
return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '增加邮箱胜利'})
3. 判断用户是否登录并返回 JSON
重要提醒:
- 只有用户登录时能力让其绑定邮箱。
- 此时前后端交互的数据类型是 JSON,所以须要判断用户是否登录并返回 JSON 给用户。
计划一:
- 应用 Django 用户认证零碎提供的
is_authenticated()
class EmailView(View):
"""增加邮箱"""
def put(self, request):
"""实现增加邮箱逻辑"""
# 判断用户是否登录并返回 JSON
if not request.user.is_authenticated():
return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})
pass
计划二:
- 自定义返回 JSON 的
login_required
装璜器- 在
meiduo_mall.utils.views.py
中
def login_required_json(view_func):
"""
判断用户是否登录的装璜器,并返回 json
:param view_func: 被装璜的视图函数
:return: json、view_func
"""
# 复原 view_func 的名字和文档
@wraps(view_func)
def wrapper(request, *args, **kwargs):
# 如果用户未登录,返回 json 数据
if not request.user.is_authenticated():
return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})
else:
# 如果用户登录,进入到 view_func 中
return view_func(request, *args, **kwargs)
return wrapper
class LoginRequiredJSONMixin(object):
"""验证用户是否登陆并返回 json 的扩大类"""
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)
return login_required_json(view)
LoginRequiredJSONMixin
的应用
class EmailView(LoginRequiredJSONMixin, View):
"""增加邮箱"""
def put(self, request):
"""实现增加邮箱逻辑"""
# 判断用户是否登录并返回 JSON
pass
Django 发送邮件的配置
1. Django 发送邮件流程剖析
send_mall()
办法介绍
地位:
- 在
django.core.mail
模块提供了send_mail()
来发送邮件。办法参数:
send_mail(subject, message, from_email, recipient_list, html_message=None)
subject 邮件题目
message 一般邮件注释,一般字符串
from_email 发件人
recipient_list 收件人列表
html_message 多媒体邮件注释,能够是 html 字符串
2. 筹备发邮件服务器
1. 点击进入《设置》界面
2. 点击进入《客户端受权明码》界面
3. 开启《受权码》,并实现验证短信
4. 填写《受权码》
5. 实现《受权码》设置
6. 配置邮件服务器
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 指定邮件后端
EMAIL_HOST = 'smtp.163.com' # 发邮件主机
EMAIL_PORT = 25 # 发邮件端口
EMAIL_HOST_USER = 'hmmeiduo@163.com' # 受权的邮箱
EMAIL_HOST_PASSWORD = 'hmmeiduo123' # 邮箱受权时取得的明码,非注册登录明码
EMAIL_FROM = '美多商城 <hmmeiduo@163.com>' # 发件人低头
发送邮箱验证邮件
重要提醒:
- 发送邮箱验证邮件是耗时的操作,不能阻塞美多商城的响应,所以须要 异步发送邮件。
- 咱们持续应用 Celery 实现异步工作。
1. 定义和调用发送邮件异步工作
1. 定义发送邮件工作
@celery_app.task(bind=True, name='send_verify_email', retry_backoff=3)
def send_verify_email(self, to_email, verify_url):
"""
发送验证邮箱邮件
:param to_email: 收件人邮箱
:param verify_url: 验证链接
:return: None
"""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)
# 有异样主动重试三次
raise self.retry(exc=e, max_retries=3)
2. 注册发邮件的工作:main.py
- 在发送邮件的异步工作中,咱们用到了 Django 的配置文件。
- 所以咱们须要批改 celery 的启动文件 main.py。
- 在其中指明 celery 能够读取的 Django 配置文件。
- 最初记得注册新增加的 email 的工作
# celery 启动文件
from celery import Celery
# 为 celery 应用 django 配置文件进行设置
import os
if not os.getenv('DJANGO_SETTINGS_MODULE'):
os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev'
# 创立 celery 实例
celery_app = Celery('meiduo')
# 加载 celery 配置
celery_app.config_from_object('celery_tasks.config')
# 主动注册 celery 工作
celery_app.autodiscover_tasks(['celery_tasks.sms', 'celery_tasks.email'])
3. 调用发送邮件异步工作
# 赋值 email 字段
try:
request.user.email = email
request.user.save()
except Exception as e:
logger.error(e)
return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '增加邮箱失败'})
# 异步发送验证邮件
verify_url = '邮件验证链接'
send_verify_email.delay(email, verify_url)
# 响应增加邮箱后果
return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '增加邮箱胜利'})
4. 启动 Celery
$ celery -A celery_tasks.main worker -l info
2. 生成邮箱验证链接
1. 定义生成邮箱验证链接办法
def generate_verify_email_url(user):
"""
生成邮箱验证链接
:param user: 以后登录用户
:return: verify_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
2. 配置相干参数
# 邮箱验证链接
EMAIL_VERIFY_URL = 'http://www.shagncheng.site:8000/emails/verification/'
3. 应用邮箱验证链接
verify_url = generate_verify_email_url(request.user)
send_verify_email.delay(email, verify_url)
验证邮箱后端逻辑
1. 验证邮箱接口设计和定义
1. 申请形式
选项 | 计划 |
---|---|
申请办法 | GET |
申请地址 | /emails/verification/ |
2. 申请参数:查问参数
参数名 | 类型 | 是否必传 | 阐明 |
---|---|---|---|
token | string | 是 | 邮箱激活链接 |
3. 响应后果:HTML
字段 | 阐明 |
---|---|
邮箱验证失败 | 响应谬误提醒 |
邮箱验证胜利 | 重定向到用户核心 |
2. 验证链接提取用户信息
def check_verify_email_token(token):
"""
验证 token 并提取 user
:param token: 用户信息签名后的后果
:return: user, None
"""
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
3. 验证邮箱后端逻辑实现
验证邮箱的外围:就是将用户的
email_active
字段设置为True
class VerifyEmailView(View):
"""验证邮箱"""
def get(self, request):
"""实现邮箱验证逻辑"""
# 接管参数
token = request.GET.get('token')
# 校验参数:判断 token 是否为空和过期,提取 user
if not token:
return http.HttpResponseBadRequest('短少 token')
user = check_verify_email_token(token)
if not user:
return http.HttpResponseForbidden('有效的 token')
# 批改 email_active 的值为 True
try:
user.email_active = True
user.save()
except Exception as e:
logger.error(e)
return http.HttpResponseServerError('激活邮件失败')
# 返回邮箱验证后果
return redirect(reverse('users:info'))
关注公众号:测试老憨,回复:商城,获取实现我的项目代码
正文完