• rest-framework之认证组件


    1、认证简介

    只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件;


    2、登录接口和token的使用

    settings.py

    INSTALLED_APPS = [
        .....
        'rest_framework',
    ]


    models.py

    from django.db import models
    
    # Create your models here.
    class User(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=64)
    
    
    # 和User表做一对一关联
    class Token(models.Model):
        # OneToOneField源码本质就是Foreignkey+unique约束
        user = models.OneToOneField(to='User')
        token = models.CharField(max_length=64)

    执行数据库迁移命令;

    在数据库里插入数据:

    image


    views.py

    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.authentication import BaseAuthentication
    from app01 import models
    from django.core.exceptions import ObjectDoesNotExist
    import uuid
    
    
    # Create your views here.
    
    class Login(APIView):
        def post(self, request):
            response={'code':100, 'msg':'登录成功'}
            name = request.data.get('name')
            pwd = request.data.get('pwd')
            try:
                # get有且只有一条才不报错,其他情况都抛异常
                user = models.User.objects.filter(name=name, pwd=pwd).get()
                # 登录成功,需要去token表中存数据
                # 生成一个唯一的id
                token = uuid.uuid4()
                # update_or_create为了添加数据时防止重复. 先去查询, 如果没有再创建, 如果有则更新
                models.Token.objects.update_or_create(user=user, defaults={'token':token})
                response['token'] = token
            except ObjectDoesNotExist as e:
                response['code']=101
                response['msg']='用户名或密码错误'
            except Exception as e:
                response['code'] = 102
                response['msg'] = str(e)
            return Response(response)


    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.Login.as_view()),
    ]


    在postman中验证:

    image


    3、认证组件

    REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案。


    接下来我们就自己实现一个基于用户名密码的认证方案:

    --认证类的局部使用

    models.py和上面相同;


    在app下写一个MyAuths.py

    from app01 import models
    from rest_framework.exceptions import AuthenticationFailed
    from rest_framework.authentication import BaseAuthentication
    
    # 认证类
    class MyAuth(BaseAuthentication):
        def authenticate(self, request):
            token = request.GET.get('token')
            token_obj = models.Token.objects.filter(token=token).first()
            if token_obj:
                # 有值表示登陆了
                # token_obj.user当前登录的user对象
                return token_obj.user,token_obj
            else:
                # 没有值表示没登陆,抛异常
                raise AuthenticationFailed('您没有登录')


    views.py中添加一个Book类,只有验证登录后才走Book:

    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app01 import models
    from django.core.exceptions import ObjectDoesNotExist
    import uuid
    # 导入MyAuth
    from app01.MyAuths import MyAuth
    
    # Create your views here.
    
    class Books(APIView):
        # 使用自定义的认证类MyAuth,可以写多个认证类
        authentication_classes = [MyAuth,]
        def get(self, request):
            # request.user就是当前登录用户,可以拿到用户名,然后再做各种操作
            print(request.user.name)
            return Response('返回了所有图书')
    
    
    class Login(APIView):
        def post(self, request):
            response={'code':100, 'msg':'登录成功'}
            name = request.data.get('name')
            pwd = request.data.get('pwd')
            try:
                # get有且只有一条才不报错,其他情况都抛异常
                user = models.User.objects.filter(name=name, pwd=pwd).get()
                # 登录成功,需要去token表中存数据
                # 生成一个唯一的id
                token = uuid.uuid4()
                # update_or_create为了添加数据时防止重复. 先去查询, 如果没有再创建, 如果有则更新
                models.Token.objects.update_or_create(user=user, defaults={'token':token})
                response['token'] = token
            except ObjectDoesNotExist as e:
                response['code']=101
                response['msg']='用户名或密码错误'
            except Exception as e:
                response['code'] = 102
                response['msg'] = str(e)
            return Response(response)


    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^books/', views.Books.as_view()),
        url(r'^login/', views.Login.as_view()),
    ]


    在postman中验证,在url后加上了正确的token,就可以走Book了

    image


    --认证类的全局使用

    在settings.py中设置,设置后视图中就不用一个个的引用了:

    # 列表里写上类名路径,可以写多个
    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.MyAuths.MyAuth",]
    }


    --认证类的局部禁用

    在全局使用时,如果某些类不想使用(比如login就不能用),怎么办呢?

    这时就要使用局部禁用了:

    # 直接在要局部禁用的视图类中,写以下内容即可
    authentication_classes = []
  • 相关阅读:
    小程序携带参数转发
    小程序开发过程中问题终结
    在小程序中使用md5处理需要加密的字符串(含中文的字符串)
    php 字符串的处理
    PHP 数组(array)
    php数学运算
    php 单双引号的区别
    PHP 结构控制 if else / switch / while / do while
    JavaScript best practices JS最佳实践
    java入门概念梳理总结
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/12515462.html
Copyright © 2020-2023  润新知