一.用户中心
由于要判断邮箱是否激活,所以需要添加一个email_active字段在User模型类中
email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
进行数据库迁移
python manage.py makemigrations
python manage.py migrate
后端接口设计:
请求方式: GET/users/infos/
返回数据:
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
id | int | 是 | 用户id |
username | str | 是 | 用户名 |
mobile | str | 是 | 手机号 |
str | 是 | email邮箱 | |
email_active | bool | 是 | 邮箱是否通过验证 |
在users/serializers.py中创建序列化器
class UserDetailSerializer(serializers.ModelSerializer):
"""
用户详细信息序列化器
"""
class Meta:
model = User
fields = ('id', 'username', 'mobile', 'email', 'email_active')
新建视图
class UserDetailView(RetrieveAPIView):
"""
获取登录用户的信息
GET /users/
既然是登录用户,我们就要用到权限管理
在类视图对象中也保存了请求对象request
request对象的user属性是通过认证检验之后的请求用户对象
"""
permission_classes = [IsAuthenticated]
serializer_class = UserDetailSerializer
def get_object(self):
return self.request.user
添加路由:
urlpatterns = [
...
#GET /users/infos/
url(r'^infos/$',views.UserDetailView.as_view(),name='detail'),
]
修改前端代码HTML和JS
二.邮箱验证
1.Django中内置了邮件发送功能
被定义在django.core.mail模块中。发送邮件需要使用SMTP服务器,这里我们使用163邮箱为例
配置好获取配置信息
# 邮箱配置信息
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = '[email protected]'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'dashabi222'
#收件人看到的发件人
EMAIL_FROM = '美多商城<[email protected]>'
将配置信息添加到setting中
在django.core.mail
模块提供了send_mail
来发送邮件
2.在user模型类中添加email_active字段
class User(AbstractUser):
"""用户模型类"""
mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
class Meta:
db_table = 'tb_users'
verbose_name = '用户'
verbose_name_plural = verbose_name
3.数据库迁移:python manage.py makemagrations
python manage.py migrate
4.点击保存按钮:
1.邮箱字段保存到数据库
2.保存后邮箱向用户绑定的邮箱发送验证链接
后端接口设计:
请求方式:PUT/users/emails/
请求参数:
参数 | 类型 | 是否必须 | 说明 |
---|---|---|---|
str | 是 | Email邮箱 |
返回数据:
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
id | int | 是 | 用户id |
str | 是 | Email邮箱 |
创建一个新视图用来处理邮件
1.只有登录的用户才能保存邮件,添加用户权限
2.添加序列化器
3.由于直接继承的UpdateAPIView,没有传递PK值,所以,也需要重写get_object方法
class EmailView(UpdateAPIView):
permission_classes = [IsAuthenticated]
serializer_class = EmailSerializer
def get_object(self):
return self.request.user
序列化器:
class EmailSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id','email']
extra_kwargs = {
'email': {
'required': True
}
}
def update(self, instance, validated_data):
email = validated_data.get('email')
instance.email = email
instance.save()
# 在这里发送激活邮件
url = instance.generic_verify_url()
from celery_tasks.email.tasks import send_verify_mail
send_verify_mail.delay(email,url)
return instance
重写update方法,在将邮件地址保存到数据库后,发送激活邮件
激活邮件需要一定的时间,我们要功能放在celery中来实现
在celery文件夹中创建email文件夹,在tasks.py文件中增加任务
from ..main import app
from django.core.mail import send_mail
from mall import settings
@app.task(name='send_verify_mail')
def send_verify_mail(email, url):
# subject, message, from_email, recipient_list,html_message=None
subject = '美多商城激活邮件'
message = ''
from_email = settings.EMAIL_FROM # 发件人
recipient_list = [email] # 收件人列表
# 可以传递 html代码
# 我们需要生成一个url,这个url中的token需要包含用户的id信息(id需要被处理)
html_message = '<p>尊敬的用户您好!</p>' \
'<p>感谢您使用美多商城。</p>' \
'<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
'<p><a href="%s">%s<a></p>' % (email, url, url)
send_mail(subject, message, from_email, recipient_list, html_message=html_message)
收件人列表添加在这里recipient_list = [email] # 收件人列表
终端使用celery命令:
celery -A celery_tasks.main worker -l info
model类里写了两个方法
此时,在收件人列表中的邮箱可以收到我们发送过去的激活邮件
def generic_verify_url(self):
serializer = Serializer(settings.SECRET_KEY, 3600)
token = serializer.dumps({'id': self.id, 'email': self.email})
return 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token.decode()
@staticmethod
def check_verify_email_token(token):
serializer = Serializer(settings.SECRET_KEY, 3600)
try:
result = serializer.loads(token)
except BadData:
return None
else:
user_id = result.get('id')
email = result.get('email')
try:
user = User.objects.get(id=user_id, email=email)
except User.DoesNotExist:
user = None
else:
return user
前面在创建URL时有调用这个方法将用户id和邮箱加密成token值发送给需要激活的邮箱
5.接下来需要实现激活邮箱功能,点击激活邮件中的URL
后端接口设计:
请求方式:GET /users/emails/verification/
请求参数:
参数 | 类型 | 是否必须 | 说明 |
---|---|---|---|
token | str | 是 | 用于验证邮箱的token |
返回数据:
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
message | str | 是 | 验证处理结果 |
1.创建一个新的视图来处理这个功能
取得token值,对token值进行解密,得到user_id和email,通过id得到user对象,将email_active字段的值改成true
class VerificationEmailView(APIView):
"""
验证激活邮箱
GET /users/emails/verification/?token=xxxx
思路:
获取token,并判断
获取 token中的id
查询用户,并判断是否存在
修改状态
返回响应
"""
def get(self,request):
token = request.query_params.get('token')
if not token:
return Response({'message':'缺少token'},status=status.HTTP_400_BAD_REQUEST)
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'})
这里用到了前面模型类中的check_verify_email_token用来解密,得到user_id和email
修改前端代码就能实现邮件的激活和绑定了
功能实现前:
功能实现后