【效能平台】登录接口开发以及JWT token认证机制(一)

1、创建子应用:users

python manage.py startapp users

2、注册子应用

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',  # 同源策略
    'rest_framework',
    'drf_yasg',  # 生成接口文档子应用
    'projects',
    'interfaces',
    'django_filters',  # DRF过滤器子应用
    'users',
]

3、采用JWT TOKEN认证

a、下载djangorestframework-jwt

pip install djangorestframework-jwt

b、settings.py文件中指定使用jwt Token认证类

REST_FRAMEWORK = {
    
    
    # 指定搜索引擎类
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter',
                                'rest_framework.filters.OrderingFilter', ],

    # 'DEFAULT_FILTER_BACKENDS':['django_filters.rest_framework.DjangoFilterBackend'],
    # 'SEARCH_PARAM': 'se',

    # 指定分页引擎类
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 3,

    # 指定用于支持coreapi的Schema
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',

    # 指定使用的认证类
    # a、在全局指定默认的认证类(认证方式)
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 1、指定jwt token认证
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ],
}

4、配置路由,可以使用用户名和密码进行认证

全局路由

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('',include('projects.urls')),

    path('docs/',include_docs_urls(title='接口测试平台API文档',description='这个是接口平台的文档')),

    re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),  # <-- 这里
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),  # <-- 这里
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),  # <-- 这里

    path('user/',include('users.urls'))
]

子路由:

urlpatterns=[
    path('',include(router.urls)),
    re_path(r'^(?P<username>\w{6,20})/count/$', views.UsernameIsExistedView.as_view()),
    re_path(r'^(?P<email>[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+)/count/$',
            views.EmailIsExistedView.as_view()),
    path('login/', obtain_jwt_token),
]

测试:
在这里插入图片描述

5、重写生成token的方法:将用户名和用户id一同输出

a、在项目公共文件utils中,新建handle_jwt_response.py文件
在这里插入图片描述

def jwt_response_payload_handler(token,user=None,response=None):
    return {
    
    
        'user_id':user.id,
        'username':user.username,
        'token':token
    }

b、还得在settings.py文件中指定token失效时间和指定访问路径,目的是:让项目运行时找到自己重写的方法;

# JWT配置
JWT_AUTH = {
    
    
    # 指定token失效时间为1天
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    # 使用自己的jwt_response_payload_handler,目的是响应结果中可以返回用户名和id
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'utils.handle_jwt_response.jwt_response_payload_handler',

}

6、测试:

在这里插入图片描述
7、现在又一个问题,当全局设置权限时:当我访问注册和登录功能时,会限制去访问;但是登录和注册不需要去限制;

解决办法:不在全局设置权限,去对应类视图中设置权限
1、在继承了APIView的类视图中,可以使用permission_classes类属性指定权限类,值为列表,可以添加多个权限类,优先级最高。
2、在继承了APIView的类视图中,可以使用authentication_classes类属性指定认证类(一般为token认证),值为列表,可以添加多个权认证类。优先级高于全局,一般无需在特定的类视图中指定
3、在settings.py中指定限流类,如果对特定的接口指定限流,那么在特定的类视图中设置throttle_classes = []

REST_FRAMEWORK = {
    
    
    ......

    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
    
    
        'anon': '100/day',  # 匿名用户
        'user': '1000/day'
    }
}
class ProjectsViewSet(viewsets.ModelViewSet):
    '''
    list:
    获取项目列表数据

    retrieve:
    获取项目详情数据

    update:
    更新项目信息

    names:
    获取项目名称
    '''
    queryset = Projects.objects.all()
    serializer_class = ProjectsSerializer

    filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]
    search_fields = ['name', 'leader', 'id']
    ordering_fields = ['name', 'leader', 'id']
    filterset_fields = ['name', 'leader']

    pagination_class = PageNumberPagination
    permission_classes = [ permissions.IsAuthenticated ]

猜你喜欢

转载自blog.csdn.net/YZL40514131/article/details/124880623