Django的Rest framework搭建自定义授权登录

这篇具有很好参考价值的文章主要介绍了Django的Rest framework搭建自定义授权登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

提示:阅读本章之前,请先阅读目录



一、前言

之前的文章有写过通过jwt认证的文章,今天这一篇是通过自定义用户认证的;

使用场景:有些API需要用户登录成功之后,才能访问;有些无需登录就能访问

解决方法:创建两张表,一张用户表,一张token表,保存用户登录成功后生产的token;
然后需要认证的视图,前台每次请求需要在请求头中携带token,后端然后对token进行验证
缺点:每个用户登录一次就需要生成一条token记录保存在数据库里,当用户量大的时候,就会增加后台服务器压力!文章来源地址https://www.toymoban.com/news/detail-615228.html

User模型

class="language-python">from django.contrib.auth.hashers import make_password, check_password
from django.db import models


# Create your models here.
class User(models.Model):
    """
    用户模型类
    """
    username = models.CharField(max_length=32,verbose_name='用户名')
    password = models.CharField(max_length=64,verbose_name='密码')
    mobile = models.CharField(max_length=11,unique=True,verbose_name='手机号')

    class Meta:
        db_table = 'user'
        verbose_name = "用户信息表"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

    def set_password(self,password):
        self.password = make_password(password)
        return None

    def check_pwd(self,password):
        return check_password(self.password,password)


class UserToken(models.Model):
    """用户token表"""
    user = models.OneToOneField(User)  # 与用户一对一关系
    token = models.CharField(max_length=64,verbose_name='token')

    class Meta:
        db_table = 'token'
        verbose_name = 'token表'
        verbose_name_plural = verbose_name

User的views

from django.shortcuts import render

# Create your views here.
from rest_framework.generics import  CreateAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView

from .utils import md5
from . import models
from . import ser

class UserLogin(APIView):
    '用户登录视图类'
    authentication_classes = []
    # 登录不需要认证
    def post(self,request):
        username = request.POST.get('username').strip()
        pwd = request.POST.get('password').strip()
        if not all([username,pwd]):
            return Response({'info':'参数不完整','code':400})
        user = models.User.objects.get(username=username)
        user.check_pwd(pwd)
        # 登录成功后生成token
        token =md5(username)
        models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
        res = {'info':'success','token':token,'code':200}
        res['data'] = ser.UserInfoSer(user).data
        return Response(res)


class UserRegister(CreateAPIView):
    """用户注册视图"""
    authentication_classes = []
    # 用户注册不需要认证
    serializer_class = ser.CreateUserSer


class UserInfoList(ListAPIView):
    """用户详情页视图"""
    serializer_class = ser.UserInfoSer
    queryset = models.User.objects.all()

User的serializers

class="language-python">from rest_framework import serializers

from . import  models

class CreateUserSer(serializers.ModelSerializer):
    """新增用户序列化器"""
    password2 = serializers.CharField(max_length=64,write_only=True)
    mobile = serializers.CharField(max_length=11,min_length=11,write_only=True)

    def validate(self, attrs):
        password = attrs['password']
        password2 = attrs['password2']
        if password != password2:
            raise serializers.ValidationError('两次密码不一致,请重新输入!')
        return attrs

    def validate_mobile(self,value):
        import re
        if not re.match(r'1[3-9]\d{9}',value):
            raise serializers.ValidationError('手机号格式不正确请重新输入!')
        return value

    def create(self, validated_data):
        del validated_data['password2']
        user = super().create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

    class Meta:
        model = models.User
        fields = '__all__'


class UserInfoSer(serializers.ModelSerializer):
    """用户详情信息序列化器"""
    class Meta:
        model = models.User
        fields = ('id','username','mobile')

utils的md5加密

import hashlib
import time

def md5(user):
    """md5 加密token"""

    ctime = str(time.time())
    m = hashlib.md5(bytes(user, encoding='utf-8'))
    m.update(bytes(ctime, encoding='utf-8'))
    return m.hexdigest()

自定义认证方法

class Authtication(BaseAuthentication):

    def authenticate(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', None)
        except:
            raise exceptions.AuthenticationFailed('用户认证失败')
        if token is None:
            raise exceptions.AuthenticationFailed('未提供认证信息')
        token = token.split(' ')[1]
        token_query = models.UserToken.objects.filter(token=token)
        if not token_query:
            raise exceptions.AuthenticationFailed('无效的token')
        # 返回(当前登录对象,token)
        return token_query.first().user, token_query.first()

    def authenticate_header(self, request):
        return 'Basic realm="user"'

    def authenticate_failed_response(self, exc):
        msg = str(exc)
        return Response({'msg': msg}, status=status.HTTP_401_UNAUTHORIZED)

配置路由

REST_FRAMEWORK = {
    # 全局使用的认证类
    "DEFAULT_AUTHENTICATION_CLASSES": ['users.auth.Authtication', ],
    "UNAUTHENTICATED_USER": None,
    "UNAUTHENTICATED_TOKEN": None,
    "DEFAULT_RENDERER_CLASSES": [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
}

总路由

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^users/', include('users.urls')),
]

分路由

from django.conf.urls import include, url
from django.contrib import admin

from . import views
urlpatterns = [
    url(r'^register/$',views.UserRegister.as_view()),
    url(r'^login/$',views.UserLogin.as_view()),
    url(r'^list/$',views.UserInfoList.as_view()),
]

rest的配置

REST_FRAMEWORK = {
    # 分页器
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    # 分页
    'PAGE_SIZE': 10,
    # 返回的时间格式
    'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S',
    # 返回的数据格式
    'DEFAULT_RENDER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    # 解析request.data
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    ],
    # 全局权限
    'DEFAULT_PERMISSION_CLASSES': [
        'common.auth.Authtication'
    ],
    # 认证方式
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    # 自定义抛出异常格式
    'EXCEPTION_HANDLER': 'common.custom_exception_handler.custom_exception_handler'
}

到了这里,关于Django的Rest framework搭建自定义授权登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django Rest_Framework(一)

    在开发Web应用中,有两种应用模式: 前后端不分离[客户端看到的内容和所有界面效果都是由服务端提供出来的。] 前后端分离【把前端的界面效果(html,css,js分离到另一个服务端或另一个目录下,python服务端只需要返回数据即可)】 前端形成一个独立的网站/独立的地址,服

    2024年02月14日
    浏览(31)
  • Django Rest_Framework(三)

    为了方便接下来的学习,我们创建一个新的子应用 opt 注册子应用 总路由,代码: 子路由,代码: 因为接下来的认证组件中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. admin运营站点的访问地址:http://127.0.0.1:8000/admin 创建管理员以后,访问admin站

    2024年02月14日
    浏览(41)
  • Django Rest_Framework(二)

    什么时候声明的序列化器需要继承序列化器基类Serializer,什么时候继承模型序列化器类ModelSerializer? 看数据是否从mysql数据库中获取,如果是则使用ModelSerializer,不是则使用Serializer drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的dja

    2024年02月14日
    浏览(27)
  • Django rest framework基本知识

    使用pycharm生成Django项目后,会生成工程目录和app目录 工程目录下5个文件,settings.py是全局配置相关的  urls.py是路有相关的 app相关的目录    models.py 数据库ORM对应的模型类  serializers.py 序列化与反序列化处理    views.py 根据request进行业务逻辑处理,返回response    admin.p

    2024年02月09日
    浏览(33)
  • django rest framework 学习笔记2

    注意:该文章部分摘抄之百度,仅当做学习笔记供小白使用,若侵权请联系删除! 显示关联表的数据,本示例会显示所有的关联的数据信息 读取到的结果器数据关联的为数字,此时需要进行一些操作可以读到正确数据 方法1: source=\\\'字段名.关联属性值\\\' 方法2 : 返回其属性值

    2024年02月20日
    浏览(30)
  • Django REST framework实现api接口

    drf 是Django REST framework的简称,drf 是基于django的一个api 接口实现框架,REST是接口设计的一种风格。 在django 上运行,首先要安装好django 和数据库驱动,后端接口就是对数据库资源的操作。 restful 接口的规范: 1、创建数据库表,在models.py中 要执行生成表的语句: 2、设置路由

    2024年02月11日
    浏览(34)
  • django rest framework 学习笔记-实战商城

     01项目环境搭建_哔哩哔哩_bilibili  本博客借鉴至大佬的视频学习笔记 创建apps文件夹放入的上面应用  创建shop数据库 mysql create database shop charset=utf8; Query OK, 1 row affected, 1 warning (0.01 sec)  公共表设计: 用户表结构设计  执行迁移文件,生成表结构 E:desktopmy_drfMyShoppython manag

    2024年02月22日
    浏览(35)
  • Django_rest_framework-drf 笔记

    Django-drf-序列化器高级用法之SerializerMethodField - 知乎 (zhihu.com) 一句话: search_fields  里的字段,是做模糊查询的字段; filter_fields  里的字段,是做精确查询的字段。 科普search_fields与filter_fields的区别_空气中的臭氧的博客-CSDN博客 一句话: related_name = \\\'test\\\' publish_obj.test.all() 

    2024年02月16日
    浏览(28)
  • django rest_framework 部署doc文档

    1.背景    在实际开发过程中,前后端分离的项目,是需要将一份完整的接口文档交付给前端开发人员,这样有利于开发速度和开发质量,以及有可能减少协同时间。 2.内容   本项目是以Python+django+rest_framework作为技术框架,在这套框架中,是有自己支持的api文档,现将实现方

    2024年01月17日
    浏览(38)
  • Django REST Framework入门之序列化器

    Django REST framework (简称:DRF)是一个强大而灵活的 Web API 工具。遵循RESTFullAPI风格,功能完善。 能简化序列化及开发REST API视图的代码,大大提高REST API的开发速度;提供灵活的路由API,内置了强大的认证和授权机制 Django REST framework 最新版使用要求 在settings.py文件的INSTALLED_

    2024年01月21日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包