Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1493
  • 博文数量: 3
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 40
  • 用 户 组: 普通用户
  • 注册时间: 2019-11-13 10:14
文章分类

全部博文(3)

文章存档

2019年(3)

我的朋友

分类: 敏捷开发

2019-11-27 16:26:47

drf组件之jwt+众享礼APP开发案例(T:/ I8O.2853.296O 认证模块

一、认证规则

全称:json web token 解释:加密字符串的原始数据是json,后台产生,通过web传输给前台存储 格式:三段式 - 头.载荷.签名 - 头和载荷用的是base64可逆加密,签名用md5不可逆加密 内容: 头(基础信息,也可以为空):加密方式、公司信息、项目组信息、... 载荷(核心信息):用户信息、过期时间、... 签名(安全保障):头加密结果+载荷加密结果+服务器秘钥 的md5加密结果

认证规则: 后台一定要保障 服务器秘钥 的安全性(它是jwt的唯一安全保障) 后台签发token(login接口 ) → 前台存储 → 发送需要认证的请求带着token → 后台校验得到合法的用户 → 权限管理

为什么要有jwt认证: 1)服务器压力小, 后台不需要存储token,只需要存储签发与校验token的算法,效率远远大于后台存储和取出token完成校验 2) jwt算法认证,更适合服务器集群部署

二、认证模块

安装:pip install djangorestframework-jwt 模块包:rest_framework_jwt

采用drf-jwt框架,后期任务只需要书写登录 为什么要重写登录:drf-jwt只完成了账号密码登录,我们还需要手机登录,邮箱登录 为什么不需要重写认证类:因为认证规则已经完成且固定不变,变得只有认证字符串的前缀,前缀可以在配置文件中配置

三、JWT使用

jwt配置;

在settings.py文件中配置,如果不配置,默认走jwt默认的

jwt插件的三个接口:

在urls.py中配置

在postman中测试一下签发token

注意:上面三个接口都是发送POST请求

四、利用JWT实现多方式登录

注:APIResponse 为自定义Response对象

# views.py from rest_framework.views import APIView from . import models,serializers from utils.response import APIResponse class LoginAPIView(APIView): # 登录接口应该禁用所有的认证和、权限,因为不管是谁都应该能进来 authentication_classes = []
    permission_classes = [] def post(self, request, *args, **kwargs): # 将数据传到序列化组件进行校验 user_ser = serializers.LoginSerializer(data=request.data)
        user_ser.is_valid(raise_exception=True) return APIResponse(msg='login success', data={ 'username': user_ser.user.username, 'token': user_ser.token
        }) 

注意:

通过user对象生成payload载荷 payload = jwt_payload_handler(user)

通过payload签发token token = jwt_encode_handler(payload)

# serializer.py from rest_framework.serializers import ModelSerializer, CharField, ValidationError, SerializerMethodField from . import models from django.contrib.auth import authenticate import re from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler class LoginSerializer(ModelSerializer): username = CharField(write_only=True)
    password = CharField(write_only=True) class Meta: model = models.User
        fields = ('username', 'password') def validate(self, attrs): # user_obj = authenticate(**attrs) # if not user_obj: #     raise ValidationError('用户名或密码错误') # 账号密码登录 ==》 多方式登录 user = self._many_method_login(**attrs) # 通过user对象生成payload载荷 payload = jwt_payload_handler(user) # 通过payload签发token token = jwt_encode_handler(payload) # 将user和token存放在序列化对象中,方便返回到前端去 self.user = user
        self.token = token return attrs # 多方式登录 (用户名、邮箱、手机号三种方式登录) def _many_method_login(self, **attrs): username = attrs.get('username')
        password = attrs.get('password') # 利用正则匹配判断用户输入的信息 # 1.判断邮箱登录 if re.match(r'.*@.*', username):
            user = models.User.objects.filter(email=username).first() # type: models.User # 2.判断手机号登录 elif re.match(r'^1[3-9][0-9]{9}$',username):
            user = models.User.objects.filter(mobile=username).first() # 3.用户名登录 else:
            user = models.User.objects.filter(username=username).first() if not user: raise ValidationError({'username': '账号有误'}) if not user.check_password(password): raise ValidationError({'password': '密码错误'}) return user 

使用postman测试代码:

五、前后台分离模式下信息交互规则

"""
1)任何人都能直接访问的接口
	请求不是是get、还是post等,不需要做任何校验

2)必须登录后才能访问的接口
	任何请求方式都可能做该方式的限制,请求必须在请求头中携带认证信息 - authorization
	
3)前台的认证信息获取只能通过登录接口
	前台提供账号密码等信息,去后台换认证信息token
	
4)前台如何完成登录注销
	前台登录成功一般在cookie中保存认证信息token,分离注销就是前台主动清除保存的token信息
"""

阅读(173) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~