Django项目总结:REST Framework 用户模块

用户模块

  • 用户注册
    • RESTful
    • 数据开始
      • 模型,数据库
      • 创建用户
        • 用户身份
          • 管理员
          • 普通
          • 删除用户
    • 注册实现
      • 添加了超级管理员生成
  • 用户登陆
    • 验证用户名密码
    • 生成用户令牌
    • 出现和注册公用post冲突
      • 添加action
      • path/?action=login
      • path/?action=register
    • 异常捕获尽量精确
  • 用户认证
    • BaseAuthentication
      • authenticate
        • 认证成功会返回 一个元组
          • 第一个元素是user
          • 第二元素是令牌 token,auth
  • 用户权限
    • BasePermission
      • has_permission
        • 是否具有权限
        • true拥有权限
        • false未拥有权限
  • 用户认证和权限
    • 直接配置在视图函数上就ok了

 

urls.py

from django.urls import path
from UserAuthAndPermission import views

urlpatterns = [
    path('users/', views.UsersAPIView.as_view()),
    path('users/<int:pk>/', views.UserAPIView.as_view(), name='usermodel-detail'),
]

 

 

model.py

from django.db import models


class UserModel(models.Model):

    u_name = models.CharField(max_length=32, unique=True)
    u_password = models.CharField(max_length=256)

    is_delete = models.BooleanField(default=False)
    is_super = models.BooleanField(default=False)

 

 

auth.py

from django.core.cache import cache
from rest_framework.authentication import BaseAuthentication

from UserAuthAndPermission.models import UserModel


# 认证
class UserAuth(BaseAuthentication):

    def authenticate(self, request):

        # 判断请求类型,GET
        if request.method == 'GET':

            # 从客户端获取token
            token = request.query_params.get('token')

            # 从缓存中寻找token
            try:
                u_id = cache.get(token)
                user = UserModel.objects.get(pk=u_id)

                return user, token
            except:
                return

 

 

permission.py

from rest_framework.permissions import BasePermission
from UserAuthAndPermission.models import UserModel


# 用户权限判断,super返回True,其他返回false
class IsSuperUser(BasePermission):

    # 重写的函数(非抽象类),最后有个返回
    def has_permission(self, request, view):

        # 判断请求类型,GET
        if request.method == 'GET':
            if isinstance(request.user, UserModel):
                return request.user.is_super
                # return True
            return False

        # 不是GET,是有权限.
        return True

 

 

serializers.py

from rest_framework import serializers

from UserAuthAndPermission.models import UserModel


class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = UserModel
        fields = ('url', 'id', 'u_name', 'u_password', 'is_super')

 

 

views.py

import uuid

from django.core.cache import cache
from rest_framework import status, exceptions
from rest_framework.generics import ListCreateAPIView
from rest_framework.response import Response

from DjangoREST.settings import SUPER_USERS
from UserAuthAndPermission.auth import UserAuth
from UserAuthAndPermission.constants import HTTP_ACTION_REGISTER, HTTP_ACTION_LOGIN
from UserAuthAndPermission.models import UserModel
from UserAuthAndPermission.permission import IsSuperUser
from UserAuthAndPermission.serializers import UserSerializer


# 创建用户
class UsersAPIView(ListCreateAPIView):

    serializer_class = UserSerializer
    queryset = UserModel.objects.all()

    # 设置只有登录用户才能获取用户列表
    # 使用token验证用户登录,使用了认证类UserAuth
    authentication_classes = (UserAuth,)

    permission_classes = (IsSuperUser,)

    # 重写post,实现登录,路径中不出现动词,(出现冲突,和注册公用post)
    # 添加action
    def post(self, request, *args, **kwargs):

        # query_params相当于之前的GET,获取动作
        action = request.query_params.get('action')

        # 根据接收到的动作,执行注册和登录
        if action == HTTP_ACTION_REGISTER:
            return self.create(request, *args, **kwargs)

        elif action == HTTP_ACTION_LOGIN:
            u_name = request.data.get('u_name')
            u_password = request.data.get('u_password')

            try:
                user = UserModel.objects.get(u_name=u_name)
                if user.u_password == u_password:
                    # 登录成功,生成身份令牌,16进制哈希码
                    # 宇宙唯一标识,.hex 将生成的uuid字符串中的 - 删除
                    token = uuid.uuid4().hex

                    # 前后端分离,token不能存储在cookie和session(基于cookie)中
                    # 使用 缓存 或 数据库 来存储token,配置cache
                    cache.set(token, user.id)

                    data = {
                        'msg': 'login success',
                        'status': 200,
                        'token': token,
                    }

                    return Response(data)
                else:
                    # 返回密码验证错误
                    raise exceptions.AuthenticationFailed

            except UserModel.DoesNotExist:
                raise exceptions.NotFound

        # 逻辑以外的异常错误
        else:
            raise exceptions.ValidationError

    def create(self, request, *args, **kwargs):

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        data = serializer.data

        u_name = data.get('u_name')

        # 若新建的用户名在预设的超级用户列表中,赋予super权限
        if u_name in SUPER_USERS:
            print('创建超级用户')
            u_id = data.get('id')

            user = UserModel.objects.get(pk=u_id)
            user.is_super = True
            user.save()
            # 超级用户创建成功后,postman页面显示True
            data.update({'is_super': True})

        headers = self.get_success_headers(serializer.data)
        return Response(data, status=status.HTTP_201_CREATED, headers=headers)


# 查询用户,默认查询集合,超级管理员可以查
class UserAPIView(ListCreateAPIView):

    serializer_class = UserSerializer

    queryset = UserModel.objects.all()

 

posted @ 2020-08-11 22:04  颗粒成仓  阅读(307)  评论(0编辑  收藏  举报