zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    Linux 部署 nginx
    Linux 部署vue项目(使用nginx)
    git 操作规范
    mysql grant权限分配(转)。
    前端优化,包括css,jss,img,cookie
    关于js里的那一堆事件
    个人作业——软件工程实践总结作业
    Unity3D 快捷键
    Beta冲刺第二天
    Beta冲刺第一天
  • 原文地址:https://www.cnblogs.com/dc2019/p/13485464.html
Copyright © 2011-2022 走看看