bifangback-在django restframework
2020-12-29 本文已影响0人
万州客
上次metis干过一次,这次bifang,还可以再干一次塞。
一,安装第三方库
1,django跨域django-cors-headers
pip install django-cors-headers
2,DRF(django restframework)安装
pip install djangorestframework
3,DRF的JWT认证安装
pip install djangorestframework-jwt
二,配置settings.py文件
配置重点关注内容如下:
# Application definition
INSTALLED_APPS = [
'account.apps.AccountConfig',
'app.apps.AppConfig',
'cmdb.apps.CmdbConfig',
'deploy.apps.DeployConfig',
'env.apps.EnvConfig',
'log.apps.LogConfig',
'release.apps.ReleaseConfig',
'server.apps.ServerConfig',
...
'rest_framework',
'corsheaders',
]
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = [
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://localhost:8000",
"http://127.0.0.1:8000"
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
# 自定义obtain_jwt_token登录参数验证
AUTHENTICATION_BACKENDS = (
'account.jwt_views.CustomJwtBackend',
)
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=365),
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
'JWT_ALLOW_REFRESH': True,
}
三,settings中定义的account/jwt_views.py内容
from datetime import datetime
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from rest_framework import status
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.views import JSONWebTokenAPIView
from rest_framework_jwt.views import ObtainJSONWebToken
from rest_framework_jwt.views import RefreshJSONWebToken
from rest_framework_jwt.views import VerifyJSONWebToken
from django.contrib.auth import get_user_model
User = get_user_model()
class CustomJwtBackend(ModelBackend):
"""
自定义用户验证,定义完之后还需要在settings中进行配置
"""
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username) | Q(email=username))
# django里面的password是加密的,前端传过来的password是明文,
# 调用check_password就会对明文进行加密,比较两者是否相同
if user.check_password(password):
return user
except Exception as e:
return None
# 不改rest_framework_jwt源码的情况下,自定义登陆后成功和错误的返回,最优雅
def jwt_response_payload_handler(token, user=None, expiration=None):
"""
自定义jwt认证成功返回数据
"""
data = {
'token': token,
'expireAt': expiration,
'user_id': user.id,
'user': {
'id': user.id,
'name': user.username,
'email': user.email,
'avatar': ''},
'is_superuser': user.is_superuser,
'permissions': [{'id': 'queryForm', 'operation': ['add', 'edit']}],
'roles': [{'id': 'admin', 'operation': ['add', 'edit', 'delete']}],
}
return {'code': 0, 'message': '欢迎回来', 'data': data}
def jwt_response_payload_error_handler(serializer, requst=None):
"""
自定义jwt认证错误返回数据
"""
data = {
'message': "用户名或者密码错误",
'status': 400,
'detail': serializer.errors,
}
return {'code': -1, 'data': data}
# jwt的返回,由JSONWebTokenAPIView,自定义它的调用和返回即可
class CustomWebTokenAPIView(JSONWebTokenAPIView):
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
user = serializer.object.get('user') or request.user
token = serializer.object.get('token')
expiration = (datetime.utcnow() +
api_settings.JWT_EXPIRATION_DELTA)
response_data = jwt_response_payload_handler(token, user, expiration)
response = Response(response_data)
if api_settings.JWT_AUTH_COOKIE:
response.set_cookie(api_settings.JWT_AUTH_COOKIE,
token,
expiration=expiration,
httponly=True)
return response
error_data = jwt_response_payload_error_handler(serializer, request)
return Response(error_data, status=status.HTTP_200_OK)
class CustomObtainJSONWebToken(ObtainJSONWebToken, CustomWebTokenAPIView):
pass
class CustomRefreshJSONWebToken(RefreshJSONWebToken, CustomWebTokenAPIView):
pass
class CustomVerifyJSONWebToken(VerifyJSONWebToken, CustomWebTokenAPIView):
pass
obtain_jwt_token = CustomObtainJSONWebToken.as_view()
refresh_jwt_token = CustomRefreshJSONWebToken.as_view()
verity_jwt_token = CustomVerifyJSONWebToken.as_view()
这个文件,不但包含了jwt认证的后端,还改写了obtain_jwt_token ..等几个函数,在接下来的Urls.py中有用。
四,定义urls.py的路由
urls.py
from account import jwt_views
urlpatterns = [
path('', index, name='index'),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')),
path('jwt_auth/', jwt_views.obtain_jwt_token),
path('refresh_jwt_auth/', jwt_views.refresh_jwt_token),
path('verify_jwt_auth/', jwt_views.verity_jwt_token),
]
五,测试jwt认证
postman上
2020-12-29 22_13_29-Postman.png
这个返回内容,要根据整个项目的认证和权限体系,在后期慢慢调整的。
{
"code": 0,
"message": "欢迎回来",
"data": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjQwNzg2MTE5LCJlbWFpbCI6ImFkbWluQGRlbW8uY29tIiwib3JpZ19pYXQiOjE2MDkyNTAxMTl9.ODHTz_Y3TFQx9WxSDLPrR867JJT31SPcMUGnsKOs6Qk",
"expireAt": "2021-12-29T13:55:19.072310",
"user_id": 1,
"user": {
"id": 1,
"name": "admin",
"email": "admin@demo.com",
"avatar": ""
},
"is_superuser": true,
"permissions": [
{
"id": "queryForm",
"operation": [
"add",
"edit"
]
}
],
"roles": [
{
"id": "admin",
"operation": [
"add",
"edit",
"delete"
]
}
]
}
}