1.认证模块

必须用户登录之后才能访问所有图书,才能修改图片,才能查询单个图书

2.怎么使用

其实本质上就是携带token字符串,然后后台拿到数据再取数据库进行校验,看是否有这个用户

先手写一个认证模块

#手写认证模块,不继承rest_framework中的类
class Auth():
    def authenticate(self,request):
        #包装后的request对象,请求来的所有东西都能拿出来
        #如果认证通过,需要返回东西,如果认证不通过,要抛异常
        token=request.GET.get('token')
        ret=models.UserToken.objects.filter(token=token).first()
        #如果有值,说明登录过了,而且带的随机字符串也是正确的
        if ret:
            return None
        else:
            #如果没有值,抛异常
            raise exceptions.APIException('您没有登录')

import uuid
class Login(APIView):
    def post(self,request):
        response={'status':100,'msg':'登录成功'}
        name=request.data.get('name')
        pwd=request.data.get('pwd')
        user=models.UserInfo.objects.filter(name=name,pwd=pwd).first()
        if not user:
            #校验失败
            response['status']=101
            response['msg']='用户名或密码错误'
        else:
            #登录成功生成一个随机字符串
            #这里还是有些问题的,每登录一次都会随机创建一个token
            token=uuid.uuid4()
            models.UserToken.objects.create(token=token,user=user)
            response['token']=token
        return JsonResponse(response,safe=False)

写认证模块,要写一个认证类,还要写一个登录接口

为了规范使用认证组件,可以在app下新建一个文件(MyAuth.py)

可以分为存数据库的方法,和不存数据局的方法,其MyAuth.py代码如下

from ff95 import settings
from app01 import models
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import APIException
from rest_framework import exceptions

#用drf的认证写一个类
# class LoginAuth(BaseAuthentication):
#存数据库版本
#     #这里的登录认证并没有使用加言处理,所以并不太安全
#     #函数名一定要叫authenticate,必须接收两个参数,第二个参数是request对象
#     def authenticate(self, request):
#         #从reque对象中取出token(也可以从其他地方取)
#         token=request.query_params.get('token')
#         #去数据库过滤,查询
#         #这里注意自己的需求是什么,是否需要带上后面的first(带上的情况比较多)
#         ret=models.UserToken.objects.filter(token=token).first()
#         if ret:
#             #能查到,说明认证通过,返回空
#             #ret.user就是当前登录用户对象
#             return ret.user,ret
#         #如果查不到,抛异常
#         raise APIException('您认证失败')

import hashlib
from ff95 import settings
def check_token(token):
    ret=True
    user_info=None
    try:
        ll=token.split('|')
        md5=hashlib.md5()
        md5.update(ll[1].encode('utf-8'))
        md5.update(settings.password.encode(('utf-8')))
        hex=md5.hexdigest()
        if not hex==ll[0]:
            ret=False
        else:
            user_info=ll[1]
    except Exception as e:
        ret=False
    return ret,user_info

class LoginAuth(BaseAuthentication):
    #不存数据库版本
    #函数名一定要叫authenticate,必须接收两个参数,第二个参数是request
    def authenticate(self, request):
        # 从request对象中取出token(也可以从其它地方取)
        token = request.query_params.get('token')
        # ret 是布尔类型,表示验证通过或失败,user_info是user的字典
        ret, user_info = check_token(token)
        print(ret,user_info)
        if ret:
            #这里return的user_info会被记录成request.user
            return user_info,None
        raise exceptions.APIException('您认证失败')

在views里代码如下

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from rest_framework.views import APIView
from django.core.serializers import serialize
from app01 import models
from app01 import MySer
from ff95 import settings
from rest_framework import exceptions
from django.core.exceptions import ObjectDoesNotExist
from app01 import MyAuth
import json

# Create your views here.
import hashlib
import time

#生成独一无二的随机字符串
def get_token(name):
    #这种方式不太安全,最好使用加言的方法
    #生成一个MD5对象
    md5=hashlib.md5()
    #往里添加值,必须是bytes格式
    #time.time()生成时间戳类型,转成字符串,再encode转成bytes格式
    md5.update(str(time.time()).encode('utf-8'))
    md5.update(name.encode('utf-8'))
    return md5.hexdigest()

def create_token(user_id):
    md5=hashlib.md5()
    md5.update(user_id.encode('utf-8'))
    md5.update(settings.password.encode('utf-8'))
    hex=md5.hexdigest()
    token=hex+'|'+user_id
    print(token)
    return token

# class Login(APIView):
#这个版本是没有加言的,不太安全
#     # 登录模块肯定不能有认证模块,如果设置了全局使用认证模块,那就局部禁用掉
#     authentication_classes = []
#     def post(self,request,*args,**kwargs):
#         response={'status':100,'msg':'登录成功'}
#         name=request.data.get('name')
#         pwd=request.data.get('pwd')
#         try:
#             user=models.UserInfo.objects.filter(name=name,pwd=pwd).first()
#             #校验成功,生成一个随机字符串
#             token=get_token(name)
#             #保存到数据库
#             #update_or_create更新或创建,没有则创建,有则更新
#             models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
#             response['token']=token
#         except ObjectDoesNotExist as e:
#             response['status']=101
#             response['msg']='用户名或密码错误'
#         except Exception as e:
#             response['status']=102
#             response['msg']=str(e)
#         return JsonResponse(response,safe=False)

class Login(APIView):
    authentication_classes = []
    def post(self,request,*args,**kwargs):
        response={'status':100,'msg':'登录成功'}
        name=request.data.get('name')
        pwd=request.data.get('pwd')
        print(request.POST)
        try:
            user=models.UserInfo.objects.get(name=name,pwd=pwd)
            user_info_json=json.dumps({'name':user.name,'id':user.pk})
            token=create_token(str(user.pk))
            #保存到数据库
            #update_or_create更新或者创建
            response['token']=token
        except ObjectDoesNotExist as e:
            response['status']=101
            response['msg']='用户名或密码错误'
        except Exception as e:
            response['status']=102
            # response['msg']='未知错误'
            response['msg']=str(e)
        return JsonResponse(response,safe=False)

class Book(APIView):
    #局部认证的话在这里写
    authentication_classes = [MyAuth.LoginAuth,]
    def get(self,request,*args,**kwargs):
        print(request.user)
        books=models.Book.objects.all()
        book_ser=MySer.BookSerializer(books,many=True)
        return JsonResponse(book_ser.data,safe=False)

其中局部禁用,或局部使用时,在views定义的类里加一行代码

authentication_classes = [LoginAuth, ]

全局使用时,则要在settings里加

REST_FRAMEWORK={
    'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],
}

rest_framework的认证系统的更多相关文章

  1. DRF内置认证组件之自定义认证系统

    自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...

  2. 基于DDD + SD.Framework实现的统一身份认证系统

    项目地址 http://git.oschina.net/lishilei0523/ShSoft.UAC 项目说明 本项目开发的目的有三: 1.作为一个使用SD.Framework框架开发的项目样板 2 ...

  3. #研发解决方案介绍#IdCenter(内部统一认证系统)

    郑昀 基于朱传志的设计文档 最后更新于2014/11/13 关键词:LDAP.认证.权限分配.IdCenter. 本文档适用人员:研发   曾经一个IT内部系统配一套帐号体系和授权   线上生产环境里 ...

  4. Radius 远程用户拨号认证系统

    RADIUS 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . RADIUS:Remote Authentication Dial In User Service,远程用户拨号认证系 ...

  5. D django 用户认证系统

    django认证系统包含三个部分:用户.权限和分组 安装 django项目默认启用了认证系统,如果不是使用django-admin.py创建项目的可以通过在settings配置文件里面的INSTALL ...

  6. [系统开发] Squid 认证系统

    一.用途 用过 Squid 的用户认证模块的同事一定知道,它有个很麻烦的问题:每过一段时间就会跳出一个重新输入密码的窗口,用户不胜其烦,我查了网上的各种配置资料,始终没有找到一个圆满的解决方法,所以编 ...

  7. Django用户认证系统(二)Web请求中的认证

    在每个Web请求中都提供一个 request.user 属性来表示当前用户.如果当前用户未登录,则该属性为AnonymousUser的一个实例,反之,则是一个User实例. 你可以通过is_authe ...

  8. Django用户认证系统(一)User对象

    User对象 User对象是认证系统的核心.用户对象通常用来代表网站的用户,并支持例如访问控制.注册用户.关联创建者和内容等.在Django认证框架中只有一个用户类,例如超级用户('superuser ...

  9. 等方案及设备提供商 有需要的可以联系QQ561454825,电话:13779953060,我们提供最专业的无线WIFI认证系统及根据您的需要修改软件

    WayOs智能路由.EasyRadius云计费.POE远程供电.WIFI城中村方案.EPON实现FTTB+LAN城中村方案. 等方案及设备提供商 有需要的可以联系QQ561454825,电话:,我们提 ...

随机推荐

  1. adb shell命令行

    d: cd D:\software\adt-bundle-windows-x86-20131030\sdk\platform-tools ————————> sdk的路径 adb shell s ...

  2. 【Latex】常用工具包

    字体篇: \usepackage{color} {\color{red}{Hello World!}} 表格篇: 1.resizebox \begin{table*}[!htb] \centering ...

  3. Android 更改按钮样式 Button Styles

    extends:http://stackoverflow.com/questions/26346727/android-material-design-button-styles   I will a ...

  4. Web 通信 之 长连接、长轮询(long polling)(转载)

    基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性. 一.什么是长连接.长轮询? 用通俗易 ...

  5. python 中的流程控制语句

    原文 if 语句 >>> x = int(input("Please enter an integer: ")) Please enter an integer: ...

  6. 连接mysql 数据库时出现2003 -can't connect to mysql server on 'localhost'(100038)的问题

    通过eclipse连接数据库是出现了以下问题 可能是由于数据库未开启造成的,你需要手动开启数据库. 手动开启数据库的方法: 1 win+r键后,在cmd中输入services.msc,点击确定 点击左 ...

  7. Nginx作为TCP负载均衡

    参考文档:https://www.cnblogs.com/stimlee/p/6243055.html Nginx在1.9版本以后支持TCP负载均衡,模块默认是没有编译的,需要编译时添加—with-s ...

  8. TOP100summit2017:Riot Games 李仁杰——大数据落地要找到数据和经验的平衡点

      壹佰案例:李仁杰老师您好,很荣幸您能参加第六届TOP100全球软件案例研究峰会,您在大数据和人工智能领域有非常丰富的经验,在这次大会上您将分享什么内容? 李仁杰:这次我主要分享的有两个方面. 一个 ...

  9. ubuntu 搜狗输入法 在中断失效

    实测是更换了皮肤后,出现在中断输入故障,乱码.在其他界面可能是正常的,更换语言没用. killall fcitx输入法突然好了(根据网友所说,更改一堆东西貌似并没有什么用) 此时关闭输入法皮肤一切正常 ...

  10. 快速排序中的partition.

    经典快速排序中的partition, 将最后一个元素作为划分点. 维护两个区域. <= x 的, >x 的区域. 划分过程中还有个待定的区域. [L,less] 区域小于x, [less+ ...