关于WEB前后端分离的要点总结(上)

前言

对于前后端分离大家可能在网上可以找到很多的文章。但是,我们今天分享的文章的英文我们的老师对于前后端的分离问题的多年工作经验的总结。今天,我们把这些经验总结知识点分享给大家,希望可以帮助到大家。

内容要点

  • 接口格式
  • 增,删,改,查及分页
  • 跨域
  • 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)

原文链接

    原文作者:雪糕
    原文地址: https://segmentfault.com/a/1190000014433017
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞