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