前言
对于前后端分离大家可能在网上可以找到很多的文章。但是,我们今天分享的文章的英文我们的老师对于前后端的分离问题的多年工作经验的总结。今天,我们把这些经验总结知识点分享给大家,希望可以帮助到大家。
内容要点
- 接口格式
- 增,删,改,查及分页
- 跨域
- ACL访问控制
- 令牌认证
接口格式
路由格式:
/ API / <模块> /
示例:
/ API /资产/
/ API / DNS /
/ API /监视器/
返回格式:
0表示请求成功,非0表示请求异常
{u'message': u'ERROR_PROXY_AUTH_FAILED', u'code': -97}
{u'message': u'SUCCESS', u'code': 0}
增,删,改,查及分页
采用django-rest-framework框架提供后端接口服务;
示例:
# -*- coding: UTF-8 -*-
class StandardResultsSetPagination(pagination.PageNumberPagination):
# 覆盖 settings 中的默认分页
page_size = 10
# page_size_query_param = 'page'
# 限制最大分页大小
max_page_size = 10
class BaseManageView(generics.ListAPIView):
serializer_class = TbRecordsSerializer
model = TbRecords
queryset = TbRecords.objects.all()
pagination_class = StandardResultsSetPagination
parser_classes = (JSONParser,)
def get_object(self, pk):
try:
return TbRecords.objects.get(pk=pk)
except TbRecords.DoesNotExist:
raise Http404
def get(self, request, *args, **kwargs):
# 分页
return super(DnsManageView, self).get(request, *args, **kwargs)
def get_queryset(self):
# 条件搜索
queryset = super(DnsManageView, self).get_queryset()
queryset = self.get_queryset_search(queryset)
return queryset
def get_queryset_search(self, queryset):
queryset = queryset.objects.filter(update_time=F('update_time') + 8)
return queryset
def post(self, request):
# 添加
data = self._parseRequest(request.body)
pass
return apiSucess("SUCCESS", 200)
def put(self, request):
# 修改
data = self._parseRequest(request.body)
pass
return apiSucess("SUCCESS", 200)
def delete(self, request, pk):
# 删除
obj = self.get_object(pk)
obj.delete()
return apiSucess("SUCCESS", 204)
def options(self, request):
# 非分页
data = TbRecords.objects.values()
return apiSucess(data, 200)
def _parseRequest(self, querydict_obj):
# 解析已提交的数据
params = QueryDict(querydict_obj).dict()
if isinstance(params, dict):
if len(params) == 1:
data = json.loads(params.keys()[0])
else:
data = params
elif isinstance(params, list):
pass
else:
pass
return data
跨域
1,通过NGINX的方式
通过在NGINX代理添加标题的方式
server {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}
2,通过后端服务方式
修改project_name / settings.py文件。
(1)添加。
INSTALLED_APPS添加corsheaders
(2)开启黑白名单,任选其一。
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*',
'localhost:8000',
'127.0.0.1:9000',
)
ACL访问控制
针对主机的权限控制
示例:
# -*- coding: UTF-8 -*-
import functools
from rest_framework import status
from rest_framework.response import Response
# 允许的白名单IP地址
ALLECT_ADDR_POOL = (
'127.0.0.1',
)
def AclHost(func):
def wrapper(request, *args, **kwargs):
username = request.request.user
method = request.request.method
if request.request.META.has_key('HTTP_X_FORWARDED_FOR'):
remote_addr = request.request.META['HTTP_X_FORWARDED_FOR']
else:
remote_addr = request.request.META['REMOTE_ADDR']
# 有多层代理
if remote_addr.count(',') >=1:
remote_addr = remote_addr.split(',')[-1].strip()
if remote_addr not in ALLECT_ADDR_POOL:
data = {'result' : {'username' : username, 'method' : method, 'remote_addr' : remote_addr}, "errmsg" : 'FORBIDDEN'}
return Response(data, status=status.HTTP_403_FORBIDDEN)
return func(request, *args, **kwargs)
return functools.wraps(func)(wrapper)
令牌认证
针对Token的权限控制
创建用户自动生成Token,基于Token的路由的访问。
示例:
(1)djuser / models.py
# -*- coding: UTF-8 -*-
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
# 针对新创建的用户生成token
@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
(2)djuser / views.py
from rest_framework.authentication import SessionAuthentication, BasicAuthentication, TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class UserManager(APIView):
# Token验证
authentication_classes = (SessionAuthentication, TokenAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user), # `django.contrib.auth.User` instance.
'auth': unicode(request.auth), # None
}
return Response(content)