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. Git工作流程最佳实践总结

    Git作为一个目前非常流行的版本管理工具,深受开发者的喜爱.那么怎样才能将Git的作用发挥的更好呢?我根据实际的项目经验,归纳总结了以下Git工作流的最佳实践.这里所谓的最佳,是经过多次项目经验后,根 ...

  2. Linux设备文件三大结构:inode,file,file_operations

    驱动程序就是向下控制硬件,向上提供接口,这里的向上提供的接口最终对应到应用层有三种方式:设备文件,/proc,/sys,其中最常用的就是使用设备文件,而Linux设备中用的最多的就是字符设备,本文就以 ...

  3. Redis集成到Spring做mybatis做二级缓存

    一.原理: 要缓存的 Java 对象必须实现 Serializable 接口,因为 Spring 会将对象先序列化再存入 Redis,比如本文中的 com.defonds.bdp.city.bean. ...

  4. WCF中序列化(XML\JSON\Dt)

    序列化 是将对象转换为容易传输的格式的过程.例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象.反之,反序列化根据流重新构造对象. 序列化描述了持久化 ...

  5. Cannot change version of project facet Dynamic Web Module to 3.0 异常问题处理

    如何解决Tomcat服务器在初始化应用的时候的以下异常问题 1,Cannot change version of project facet Dynamic Web Module to 3.0 2,O ...

  6. day_5.21 py 高级编程

    1.禁止模块之间的循环调用 2.浅拷贝    只拷贝引用!!\ 3. 深拷贝  只要里面有引用就继续拷贝 4.copy,copy() 5. '''2018-5-21 11:39:52就业班 py高级 ...

  7. javascript基础学习系列-原型链模式

    1.demo代码如下: 2.画图如下: 3.规则: 1)每一个函数数据类型(普通函数/类)都有一个天生自带的属性:prototype(原型),并且这个属性是一个对象数据类型的值 2)并且prototy ...

  8. HTTP 响应状态码

    MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status section 10 of RFC 2616 https://tools.ie ...

  9. CCPC-Wannafly Winter Camp Day5 Div1 - Sorting - [线段树]

    题目链接:https://zhixincode.com/contest/22/problem/I?problem_id=314 样例输入 1 5 9 31 5 3 2 41 1 52 1 51 1 1 ...

  10. 1.7Oo局部变量和成员变量执行顺序

    import java.util.Scanner; public class booleann { private float fWidth; private float fHeight; void ...