02: djangorestframework使用

1.1 djangorestframework登录、认证和权限

  1、认证与权限相关模块

      

# -*- coding: utf-8 -*-
from django.utils import six
from rest_framework.response import Response
from rest_framework.serializers import Serializer


class JsonResponse(Response):
    """
    An HttpResponse that allows its data to be rendered into
    arbitrary media types.
    """

    def __init__(self,
                 data=None,
                 code=None,
                 desc=None,
                 status=None,
                 template_name=None,
                 headers=None,
                 exception=False,
                 content_type='application/json; charset=utf-8'):
        """
        Alters the init arguments slightly.
        For example, drop 'template_name', and instead use 'data'.
        Setting 'renderer' and 'media_type' will typically be deferred,
        For example being set automatically by the `APIView`.
        """

        super(Response, self).__init__(None, status=status)

        if isinstance(data, Serializer):
            msg = ('You passed a Serializer instance as data, but '
                   'probably meant to pass serialized `.data` or '
                   '`.error`. representation.')
            raise AssertionError(msg)

        self.data = {"code": code, "desc": desc, "data": data}
        self.template_name = template_name
        self.exception = exception
        self.content_type = content_type

        if headers:
            for name, value in six.iteritems(headers):
                self[name] = value
common\api_response.py 返回统一标准json数据
# -*- coding:utf-8 -*-
from __future__ import absolute_import

from rest_framework import status as http_status
from common.api_response import JsonResponse

__all__ = ['created_success']


def ajax_data(data=None,
              code=http_status.HTTP_200_OK,
              desc=None,
              status=http_status.HTTP_200_OK):

    return JsonResponse(data=data, code=code, desc=desc, status=status)


def success(data=None, desc=None):
    return ajax_data(data=data, desc=desc)


def error(data=None, desc=None):
    return ajax_data(
        data=data, code=http_status.HTTP_500_INTERNAL_SERVER_ERROR, desc=desc)


def created_success(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_201_CREATED,
        desc=desc,
        status=http_status.HTTP_201_CREATED)


def conflict(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_409_CONFLICT,
        desc=desc,
        status=http_status.HTTP_409_CONFLICT)


def accepted(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_202_ACCEPTED,
        desc=desc,
        status=http_status.HTTP_202_ACCEPTED)


def not_implemented(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_501_NOT_IMPLEMENTED,
        desc=desc,
        status=http_status.HTTP_501_NOT_IMPLEMENTED)


def unauthorized(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_401_UNAUTHORIZED,
        desc=desc,
        status=http_status.HTTP_401_UNAUTHORIZED)


def not_found(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_404_NOT_FOUND,
        desc=desc,
        status=http_status.HTTP_404_NOT_FOUND)


def bad_request(data=None, desc=None):
    return ajax_data(
        data=data,
        code=http_status.HTTP_400_BAD_REQUEST,
        desc=desc,
        status=http_status.HTTP_400_BAD_REQUEST)
common\ajax.py 将所有返回封装成标准状态码格式
#!/usr/bin/python
# -*- coding: utf-8 -*-
from rest_framework.views import APIView
from common.auth.authentication import IsAuthenticated, IsOwnerOrReadOnly


class BaseViews(APIView):
    authentication_classes = (IsAuthenticated,)
    permission_classes = (IsOwnerOrReadOnly,)

    def __init__(self):
        super(BaseViews).__init__(BaseViews, self)
        self.user = None

    def perform_authentication(self, request):
        self.user = self.get_authenticators()[0].authenticate(request).user
common\auth\base_views.py 自定义认证和权限的基类
#!/usr/bin/python
# -*- coding: utf-8 -*-
from rest_framework import exceptions
from rest_framework import authentication
from rest_framework import permissions
from users.models import VueUserToken


class IsAuthenticated(authentication.BaseAuthentication):
    """
    Custom permission to only allow owners of an object to edit it.
    """

    def authenticate(self, request):
        auth = request.META.get('HTTP_AUTHORIZATION', None)
        if auth is None:
            raise exceptions.NotAuthenticated()
        token = VueUserToken.objects.filter(key=auth)
        try:
            request.user = token[0].user
        except IndexError:
            raise exceptions.NotAuthenticated('Invalid input Authenticated')
        return request

    def authenticate_header(self, request):
        msg = 'Invalid token.Please get token first'
        return exceptions.NotAuthenticated(msg)

class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    是否有操作权限: 只有返回True才有操作权限,
    """

    def has_permission(self, request, view):

        if False:  # 这里暂且不进行权限验证
            raise exceptions.ParseError('您没有操作的权限')
        return True
common\auth\authentication.py 验证token是否合法,是否有请求操作权限
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import uuid
import hmac
from django.contrib.auth.models import User
from users.models import VueUserToken
from django.utils import timezone


def create_token():
    key = str(uuid.uuid1())
    h = hmac.new(b"123456", key.encode(encoding="utf-8"))
    return h.hexdigest()


def updata_token(user):
    userobj = User.objects.filter(username=user)
    if userobj:
        userobj = userobj[0]
    else:
        userobj = User.objects.create(username=user)
    tokenobj = VueUserToken.objects.filter(user=userobj)
    tokenid = create_token()
    if tokenobj:
        now = timezone.now()
        last_login_time = tokenobj[0].created
        interval = now - last_login_time
        if interval.seconds > 86400:
            tokenobj = tokenobj[0]
            tokenobj.key = tokenid
            tokenobj.save()
            return tokenobj.key
        return tokenobj[0].key
    else:
        tokenobj = VueUserToken.objects.create(user=userobj,key=tokenid)
        return tokenobj.key
common\auth\handle_token.py 用户身份验证通过后生成token

  2、创建users这个APP,并测试上面认证与权限的使用

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
    'rest_framework'
]
settings.py 注册app
from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^users/', include('users.urls')),
]
urls.py 总url
__author__ = 'tom'
# -*-coding=utf8-*-
from django.conf.urls import url
from users import views

urlpatterns = [
    url(r'^v1/user/login/$', views.LoginViewSet.as_view(), name='user-login'),
    url(r'^v1/userinfo/$', views.UserInfoViewSet.as_view(), name='user-info'),
]
users/urls.py APP中url
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class VueUserToken(models.Model):
    user = models.OneToOneField(User, verbose_name='用户名',unique=True)
    key = models.CharField(max_length=255,null=True,blank=True)
    created = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Vue API Token'
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return self.user.username
users/models.py 创建token表
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import HttpResponse
from rest_framework.views import APIView
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
import json
from common import ajax
from common.auth.base_views import BaseViews
from common.auth import handle_token


class LoginViewSet(APIView):
    """用户登录"""
    def __init__(self):
        super(LoginViewSet, self).__init__()

    def get(self,request):
        return HttpResponse('ok')

    def post(self, request, *args, **kwargs):
        user = request.data.get('username', '')
        pwd = request.data.get('password', '')
        username = authenticate(username=user, password=pwd)
        if username is None:
            return ajax.bad_request(desc='账号密码输入错误!')
        else:
            key = handle_token.updata_token(user)
            return ajax.success(data=str(key))


class UserInfoViewSet(BaseViews):
    '''获取用户信息'''
    def __init__(self):
        super(UserInfoViewSet, self).__init__()

    def get(self, request, *args, **kwargs):
        username = request.query_params.get('username')
        data = {'username':username}
        return ajax.success(desc='sucess',data=data)

    def post(self, request):
        usernamne = request.data.get('username')
        password = request.data.get('password')
        if usernamne is None or password is None:
            return ajax.bad_request(desc='抱歉,输入的信息不全')
        has_user = User.objects.filter(username=usernamne)
        if has_user:
            return ajax.bad_request(desc='用户名已经存在')
        user = User()
        user.set_password(password)                         #让密码更安全,设置密码,给密码加盐
        user.username = usernamne
        user.is_staff = True
        user.is_superuser = True
        user.save()
        return ajax.success(desc='创建成功')
users/views.py 登录、认证、权限使用举例

猜你喜欢

转载自www.cnblogs.com/xiaonq/p/10124104.html
今日推荐