Django-rest-framework 基础应用之用户登录学习

前言

本次学习较为紧促,因为之前有做过Django的小项目,所以跳过了一些基础,这次就直接进入Django-rest-framework的学习。


登陆创建Token

创建"Tutorial"项目和"api"app

首先我们先把项目建起来

 django-admin startproject Tutorial
 python manage.py startapp api

创建用户表

然后我们需要把需要的model也给建起来
修改api/models.py如下

from django.db import models


class UserInfo(models.Model):
    user_type_choices = (
        (1, 'normal'),
        (2, 'VIP'),
        (3, 'SVIP'),
    )
    user_type = models.IntegerField(choices=user_type_choices)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)


class UserToken(models.Model):
    user = models.OneToOneField(to='UserInfo', on_delete=models.CASCADE)
    token = models.CharField(max_length=64)

值得注意的是,Django 2.0 后,models.ForeignKey() 函数 和 models.OneToOneField() 中的 on_delete 参数不再默认为 CASCADE ,而是必须手动写入参数

然后我们执行数据迁移

python manage.py makemigrations
python manage.py migrate

这边我遇到了pycharm数据库显示为空的状况,通过这边文章得到了解决

现在打开db.sqlite3,我们可以往里面添加如下内容
在这里插入图片描述
好了,用户表也创建完了,接下来我们需要创建api了

创建api

写好view
修改api/views.py如下
具体就是通过判断username和password是否正确,然后通过md5生成token

from django.http import JsonResponse
from rest_framework.views import APIView
from api import models
# 通过md5,对用户名通过时间加密
def md5(user):
    import hashlib
    import time
    ctime = str(time.time())
    m = hashlib.md5(bytes(user, encoding='utf-8'))
    m.update(bytes(ctime, encoding='utf-8'))
    return m.hexdigest()

class AuthView(APIView):

    def post(self, request, *args, **kwargs):
        # 设置返回的code和msg
        ret = {'code': 1000, 'msg': None}
        try:
            #获取post的data
            user = request.POST.get('username')
            pwd = request.POST.get('password')
            #通过filter拿到唯一的object
            obj = models.UserInfo.objects.filter(username=user, password=pwd).first()
            #若拿不到则返回obj为none,返回错误代码
            if not obj:
                ret['code'] = 1001
                ret['msg'] = "username or pwd error"
            else:
                #生成token,创建或者更新到userToken表中
                token = md5(user)
                models.UserToken.objects.update_or_create(user=obj, defaults={'token':token})
        #抓取异常,返回错误代码
        except Exception as e:
            ret['code'] = 1002
            ret['msg'] = "exception error"
        #最后post请求会返回一个json
        return JsonResponse(ret)

更新路由

修改Tutorial/urls.py如下

from django.contrib import admin
from django.urls import path
from api import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/auth/', views.AuthView.as_view())
]

那么我们的登陆获取token的雏形就出来了,接下来我们测试一下代码是否能走得通

测试

通过postman
设置好body中的key和value
经过post测试,返回通过
在这里插入图片描述
查看数据库中的userToken,发现Token已经生成了,并且相同用户每次post通过后Token将会更新
在这里插入图片描述
那么接下来我们就可以做token的认证了


Token认证

比如说我们现在来一个订单,但这个订单需要通过了认证,才可以获得

更新model

那么我们首先创建一个订单的model
在model.py中加入如下

class Order(models.Model):
    gender_choices = (
        (1, 'man'),
        (2, 'woman'),
    )
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    gender = models.IntegerField(choices=gender_choices)
    content = models.CharField(max_length=64)

再次通过数据迁移更新到数据库中

python manage.py makemigrations
python manage.py migrate

然后在数据库中加入如下数据在这里插入图片描述
准备好数据后,我们开始更新views

更新views和url并测试

我们在views.py下面加入新的class,这边有一篇文章讲解了几种简单的model转化json的方法,可以看一下

class OrderView(APIView):

    def get(self, request, *args, **kwargs):
        ret = {'code':1000, 'msg':None, 'data':None}
        try:
            #较为简单的model转化为json方法
            orders = models.Order.objects.all().values()
            ret['data'] = list(orders)

        except Exception as e:
            ret['code'] = 1002
            ret['msg'] = "exception error"

        return JsonResponse(ret)

然后将其加入路由

    path('api/v1/order/', views.OrderView.as_view()),

现在我们通过postman就可以返回我们的所需要的orderlist了
在这里插入图片描述
好了,那么现在我们就要把认证加入进去

加入认证class

现在我们在views.py中加入认证class

这次需要加入django-rest-framework的生成认证错误的方法,还有基本的认证方法

from rest_framework import exceptions
from rest_framework.authentication import BasicAuthentication

然后我们开始写认证class
Django获取Header中的信息的文章

class Authtication(object):

    def authenticate(self, request):
        #用META,参数必须前面跟上HTTP_并且全部大写,例如username就为,HTTP_USERNAME
        token = request.META.get('HTTP_TOKEN')
        token_obj =  models.UserToken.objects.filter(token=token).first()
        if not token_obj:
            #必须用django-rest-framework自带的exception
            #可以直接找到问题并且内部会return掉返回一个问题并且带有detail
            raise exceptions.AuthenticationFailed(detail='auth fail')
        #在rest framework内部会讲这两个字段赋值给request,以供后续操作使用
        #具体可以在下面的OrderView中显示为 request.user = token_obj.user
        #                              request.auth = token_obj
        return (token_obj.user, token_obj)
	
	#这个是BasicAuthentication中的方法,return None就行了,算是通过auth
    def authenticate_header(self, requst):
        pass

然后我们在OrderView中加入认证

class OrderView(APIView):

    authentication_classes = [Authtication,]

    def get(self, request, *args, **kwargs):
	...

这样我们的认证就加好了,接下来我们就通过postman来测试一下

如果我们没有把token加入到Headers,那么将会收到exceptions.AuthenticationFailed(detail=‘auth fail’)的forbid消息
在这里插入图片描述
当我们加入Token之后,就可以成功返回正确的数据了

在这里插入图片描述

总结

我们以上面的方法,可以获得一个简单的登陆系统,可以简单的以登陆,获得并且刷新token,然后在需要进行认证的view加入认证,通过带有持有token的header的request,完成认证。
实际上本次学习极少用到django-rest-framework的知识,接下来慢慢通过学习来补全这一块知识后,再发一个总结。

接下来得做一个react-native项目的api,
具体实现十分简单
文章列表(list(Article.object.all().values), 任何人都看)
文章的增删改查(需要认证, 任何人都能看,但是增删改查需要认证)
实现简单的注册功能(创建用户
实现登陆功能(拿取token

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django-rest-framework是一个用于构建Web API的强大框架,它提供了许多有用的工具和库,可以帮助我们轻松地构建出一个安全可靠的用户注册和登录系统。 下面是一个简单的Django-rest-framework用户注册与登录的实现: 首先,我们需要安装Django-rest-framework: ``` pip install djangorestframework ``` 接着,我们需要在settings.py文件中添加以下配置: ```python INSTALLED_APPS = [ # ... 'rest_framework', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], } ``` 上面的配置将启用TokenAuthentication身份验证和IsAuthenticated权限,这将确保只有已登录的用户才能访问我们的API。 现在,我们可以创建一个名为"users"的Django应用程序,并定义以下模型: ```python from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): pass ``` 接着,我们需要定义序列化器来将User模型转换为JSON格式: ```python from rest_framework import serializers from .models import User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('username', 'email', 'password') extra_kwargs = {'password': {'write_only': True}} def create(self, validated_data): user = User.objects.create_user( username=validated_data['username'], email=validated_data['email'], password=validated_data['password'] ) return user ``` 上面的代码定义了一个UserSerializer序列化器,将User模型转换为JSON格式。我们使用Meta类来指定模型和要序列化的字段,以及一些额外的参数。在create方法中,我们使用create_user方法创建新用户。 现在,我们可以定义视图来处理用户注册和登录请求: ```python from rest_framework import generics, permissions, status from rest_framework.response import Response from rest_framework.authtoken.models import Token from rest_framework.views import APIView from django.contrib.auth import authenticate, login from .models import User from .serializers import UserSerializer class RegisterView(generics.CreateAPIView): queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [permissions.AllowAny] def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) class LoginView(APIView): permission_classes = [permissions.AllowAny] def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(request, username=username, password=password) if user is not None: login(request, user) token, created = Token.objects.get_or_create(user=user) return Response({'token': token.key}) else: return Response({'error': 'Invalid credentials'}) ``` 上面的代码定义了RegisterView和LoginView视图。RegisterView视图处理用户注册请求,LoginView视图处理用户登录请求。我们在视图中使用UserSerializer序列化器来验证输入数据,并使用TokenAuthentication身份验证来保护API。 现在我们已经完成了用户注册和登录的实现。可以使用POST请求来测试我们的API: - 用户注册: ``` POST /api/register/ { "username": "testuser", "email": "[email protected]", "password": "testpassword" } ``` - 用户登录: ``` POST /api/login/ { "username": "testuser", "password": "testpassword" } ``` 如果登录成功,API将返回一个包含Token身份验证密钥的JSON响应。现在,我们可以将此密钥用于所有受保护的API请求中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值