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