python-Django-rest_framework 用戶的登錄注冊及用戶認證及權限控制


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM