DRF用户权限和Django发送邮件、itsdangerous模块的使用

DRF用户权限和Django发送邮件、itsdangerous模块的使用

  • DRF的用户权限
    • 全局设置权限
    • 单个视图设置
  • Django的发送邮件功能
    • 先在自己的设置settings.py文件配置
    • 在serializers.py文件发送邮件
  • Django的itsdangerous模块
    • 使用加密token
    • 解密token
  • 发送验证邮件的逻辑和实例
    • 基本逻辑:
    • 利用put请求发送更新或者验证原邮件
    • 激活邮箱

DRF的用户权限

看官方文档:https://www.django-rest-framework.org/api-guide/permissions/

全局设置权限

DEFAULT_PERMISSION_CLASSES用来设置默认权限策略

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
    	# 默认都需要登录验证
        'rest_framework.permissions.IsAuthenticated',
    )
}

如果未指定,则此设置默认为允许不受限制的访问:

'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',
)

单个视图设置

APIView:

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)

或者,如果您使用的是@api_view具有基于功能的视图的装饰器。

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)

Django的发送邮件功能

需要开通邮箱里的POP3/SMTP服务,以qq邮箱为例:在设置-账户里开通
DRF用户权限和Django发送邮件、itsdangerous模块的使用_第1张图片
会获取一个独立授权码,填到下面的EMAIL_HOST_PASSWORD即可

先在自己的设置settings.py文件配置

# 默认邮箱配置
EMAIL_USE_SSL = True
EMAIL_HOST = 'smtp.qq.com'  # smtp服务器地址,163是smtp.163.com
EMAIL_PORT = 465  # 端口号25 or 465
EMAIL_HOST_USER = '[email protected]'  # 帐号
EMAIL_HOST_PASSWORD = 'bftekkiohcuybfei'  # QQ邮箱的独立授权码
EMAIL_FROM = 'SHANGHUI<[email protected]>'  # 收件人看到的发件人,尖括号中的必须与上面的user一致
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

在serializers.py文件发送邮件

from django.core.mail import send_mail
from shanghuishop.settings import dev
# 发送邮件
    # 发送邮件
    from_email = settings.DEFAULT_FROM_EMAIL
    url = 'http://127.0.0.1:8000/users/email_verify/'+token+'/'
    html_msg = '激活链接地址'
    # 可以用html_message然后加个a标签确认可以点击
    # 必填四个参数,1是邮件主题,2是邮件信息,可以为空用html_message代替
        # 3是发件人,4是收件人,类型为一个列表
    send_mail('用户邮件激活', '点击链接激活邮箱:'+ url, from_email, ['[email protected]', ], html_message='点击这个激活:'+html_msg)

发送效果为:
DRF用户权限和Django发送邮件、itsdangerous模块的使用_第2张图片

Django的itsdangerous模块

先pip安装

pip install itsdangerous

使用加密token

from itsdangerous import TimedJSONWebSignatureSerializer as TJWSS
from shanghuishop.settings import dev

# # tjwss = TJWSS(秘钥, 有效期(单位秒)) 不写的话默认时间为3600秒
    # Django项目中setting中自带了一个秘钥直接使用,其他地方 可以先生成一个秘钥,再使用
    tjwss = TJWSS(dev.SECRET_KEY, 60*10)

    # 要加密的数据
    data = {
        "email": validated_data['email'],
    }
    # 加密 tjwss.dumps(数据), 返回bytes类型
    token = tjwss.dumps(data).decode()

解密token

from itsdangerous import TimedJSONWebSignatureSerializer as TJWSS
from shanghuishop.settings import dev

# 解密 需要跟加密使用一样的秘钥以及有效期
tjwss = TJWSS(dev.SECRET_KEY, 300)

try:
	data = tjwss.loads(token)
# 验证失败,会抛出itsdangerous.BadData异常
except BadData:
	return None

发送验证邮件的逻辑和实例

基本逻辑:

  • 利用itsdangerous模块对链接中的用户信息加密,生成加密后的用户信息token;
  • 调用Django发送邮件的相关方法,进行发送邮件(邮件的配置已经配置好);
  • 邮件发送的链接中有一个可变参数,包含着用户id加密后的信息;
  • 用户接收到邮件之后,点击链接,跳转到对应的视图类进行处理;
  • 负责激活的视图类,解密用户的信息,获取用户id,查询到对应用户(在这个过程会判断被加密的信息是否超时);
  • 将对应用户中数据库中用户表中 is_active 字段的值改为1,表示此用户被激活;
  • 跳转到首页;

利用put请求发送更新或者验证原邮件

在views.py写一个put请求视图类:

class EmailView(UpdateAPIView):
    permission_classes = (IsAuthenticated,)
    serializer_class = EmailSerClass
    # 获取到email,校验邮箱,数据更新,发送邮件

    def get_object(self):
        return self.request.user

写一个序列化器,这里发送的是我们要使用的验证地址,下面继续写验证地址的逻辑

class EmailSerClass(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ('id', 'email')

    def validate(self, attrs):

        return attrs

    def update(self, instance, validated_data):
        '''
        :param instance: 视图传递过来的实例对象,get_object获取的
        :param validated_data: 校验完的数据
        :return:
        '''
        print('1111111111111111111111111')
        print(validated_data)
        instance.email = validated_data['email']
        instance.save()
        # 生成激活链接
        # # tjwss = TJWSS(秘钥, 有效期(单位秒)) 不写的话默认时间为3600秒
        # Django项目中setting中自带了一个秘钥直接使用,其他地方 可以先生成一个秘钥,再使用
        tjwss = TJWSS(settings.SECRET_KEY, 60*60)

        # 要加密的数据
        data = {
            'id': instance.id,
            "email": instance.email,
        }
        # 加密 tjwss.dumps(数据), 返回bytes类型
        token = tjwss.dumps(data).decode()

        # 发送邮件
        from_email = settings.DEFAULT_FROM_EMAIL
        url = 'http://127.0.0.1:8000/users/email_verify/'+token+'/'
        html_msg = '激活链接地址'
        # 可以用html_message然后加个a标签确认可以点击
        # 必填四个参数,1是邮件主题,2是邮件信息,可以为空用html_message代替
        # 3是发件人,4是收件人,类型为一个列表
        send_mail('用户邮件激活', '点击链接激活邮箱:'+ url, from_email, ['[email protected]', ], html_message='点击这个激活:'+html_msg)
        return instance

激活邮箱

先写序列化器:

class EmailVerifySerClass(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ('id', 'email', 'is_email_active')

    def update(self, instance, validated_data):
        instance.id = validated_data['id']
        instance.email = validated_data['email']
        instance.is_email_active = validated_data['is_email_active']
        return instance

再写激活视图类逻辑,先校验再设置Users对象的is_email_active为1

class EmailVerifyView(APIView):
    # 激活邮箱
    def get(self, request, token):
        # 用itsdangerou模块的方法进行解密
        ts_obj = TJWSS(settings.SECRET_KEY, 60 * 30)
        user_obj = ts_obj.loads(token)
        # 设置邮箱验证成功
        user_obj['is_email_active'] = 1
        print('hhhhhhhhhhhhhhhhhhhh:')
        print(user_obj)
        # 反序列化验证
        ser = EmailVerifySerClass(data=user_obj)
        # 验证并打印是否验证成功
        print(ser.is_valid())
        print('ser.errors:', ser.errors)
        print(ser.validated_data)
        # 根据id值获取用户
        user = Users.objects.get(id=user_obj['id'])
        # 设置激活状态为1,保存
        user.is_email_active = 1
        user.save()
        return Response('ok')

你可能感兴趣的:(itsdangerous,Django)