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 登录、认证、权限使用举例
原文地址:https://www.cnblogs.com/xiaonq/p/10124104.html
时间: 2024-10-25 10:40:52