python-Django-rest_framework 用户的登录注册及用户认证及权限控制

[2021-12-21 22:20更新]当前项目是两年前练习做的项目:https://files.cnblogs.com/files/Vera-y/mydjango.zip

 models.py

# models.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_delect = models.BooleanField(default=False)
    # 是否是超级管理员
    is_super = models.BooleanField(default=False)

views.py

# views.py
from django.core.cache import cache
# 创建用户(用户的注册和登录),(超级管理员)查询用户

# 创建用户
import uuid
from rest_framework import status, exceptions
from rest_framework.generics import ListCreateAPIView

# ListCreateAPIView:可以用于用户的创建和查询
from rest_framework.response import Response

from UserAuth.auth import UserAuth
from UserAuth.contants import POST_ACTION_REGISTER, POST_ACTION_LOGIN
from UserAuth.models import UserModel
from UserAuth.permissions import Userpermission
from UserAuth.serializers import UserSerializer

# 所有用户
# ListCreateAPIView中post用于处理用户创建的【Create()】,
from mydjango.settings import SUPER_USERS


class UsersAPIView(ListCreateAPIView):
    # 序列化类
    serializer_class = UserSerializer
    # 查询集和结果集
    queryset = UserModel.objects.all()
    # 用户验证
    authentication_classes = (UserAuth,)
    # 权限控制
    permission_classes = (Userpermission,)
    # 直接进行权限控制permission (如上)
    # 重写get请求,判断request.user 是否是UserModel中的一个实例
    # def get(self, request, *args, **kwargs):
    #     if isinstance(request.user, UserModel):
    #         if request.user.is_super:
    #             return self.list(request, *args, **kwargs)
    #         else:
    #             raise exceptions.NotAuthenticated  # 没有超级管理员的权限
    #     else:
    #         raise exceptions.NotAuthenticated   # 用户没有登录,没有权限访问

    # 同一个post做把登录和注册同时完成
    def post(self, request, *args, **kwargs):
        action = request.query_params.get('action')
        # 若参数为register则为注册,创建用户
        if action == POST_ACTION_REGISTER:
            return self.create(request, *args, **kwargs)
        elif action == POST_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:
                    # 生成令牌,传入客户端和放入服务器缓存或者数据库
                    token = uuid.uuid4().hex
                    # 把token放入缓存,注意Redis在settings中的配置
                    cache.set(token, user.id)
                    # 并传入客户端
                    data = {
                        'msg': 'ok',
                        'status': 200,
                        'token': token
                    }
                    return Response(data)
                else:
                    raise exceptions.AuthenticationFailed   # 用户密码错误
            except UserModel.DoesNotExist:
                raise exceptions.NotFound   # 用户名错误
        else:
            raise exceptions.ValidationError  # 验证错误,传入的不是POST请求

    # 创建用户
    # 重写的CreateModelMixin中的方法:用于用户的创建
    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')
        # 判断是否是创建的超级用户
        if u_name in SUPER_USERS:
            u_id = data.get('id')
            user = UserModel.objects.get(pk=u_id)  # 拿到对应的用户
            user.is_super = True  # 设置为超级用户o0
            user.save()
            data.update({'is_super': True})     # 创建了超级用户,在返回客户端的时候也把对应修改做了

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


# 单个用户,只用于展示
class UserAPIView(RetrieveAPIView):
    serializer_class = UserSerializer
    queryset = UserModel.objects.all()

serializers.py

# serializers.py
# 用户序列化
from rest_framework import serializers

from UserAuth.models import UserModel


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserModel
        # 要显示出来的字段
        fields = ('id', 'u_name', 'u_password', 'is_super')

contants.py

# contants.py
# 只做常量值
# 这里用作views.py 中action的常量操作

POST_ACTION_LOGIN = 'login'
POST_ACTION_REGISTER = 'register'

auth.py  

auth.py
# 用户认证
from django.core.cache import cache
from rest_framework.authentication import BaseAuthentication

from UserAuth.models import UserModel


class UserAuth(BaseAuthentication):
    # 验证user及token
    def authenticate(self, request):
        # 判断是否是get请求,其他请求直接可以访问
        if request.method == 'GET':
            # 从请求地址栏获取token(query_params)
            token = request.query_params.get('token')
            try:
                u_id = cache.get(token)
                user = UserModel.objects.get(pk=u_id)
                return user, token
            except:  # 若验证没成功返回None
                return

permissions.py

# permissions.py
# 权限控制
from rest_framework.permissions import BasePermission

from UserAuth.models import UserModel


class Userpermission(BasePermission):
    # 重写方法,进行权限限制
    def has_permission(self, request, view):
        # 针对get请求的权限控制
        if request.method == 'GET':
            # 在用户存在的情况下
            if isinstance(request.user, UserModel):
                # 用户是超级用户返回True
                return request.user.is_super
            return False
        return True
posted @ 2019-12-26 15:31  yin_zhaozhao  阅读(2936)  评论(3编辑  收藏  举报