• DRF框架之认证、授权和登录


    一、认证

    1.Browsable API页面认证与JWT认证比较

    1.Browsable API页面认证

    • 指定permission_classes
    • 添加rest_framework.urls路由

    2.Json Web Token认证

    • 最常用的认证方式
      • Session认证
      • Token认证
    • Session认证
      • 保存在服务端,增加服务器开销
      • 分布式架构中,难以维持Session会话同步
      • CSRF攻击风险
    • Token认证
      • 保存在客户端
      • 跨语言、跨平台
      • 拓展性强
      • 鉴权性能高
    • JWT
      • 由三部分组成
        • header、playload、signature
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhemF6aWUiLCJhdWQiOiJ1c2VycyIsImlhdCI6MTU5NTY3NTA1NiwiZXhwIjoxNTk2Mjc5ODU2LCJ1c2VyX2lkIjozMDI3NTQxfQ.vJPcwpw4_WBLGBkXO3SUPbyfgDzk4S3FwWzJrCtvhwA
      • header
        • 声明类型
        • 声明加密算法,默认为HS256
        • base64加密,可以解密
      • playload
        • 存放过期时间、签发用户等
        • 可以添加用户的非敏感信息
        • base64加密,可以解密
      • signature
        • 有三部分组成
        • 使用base64加密之后的header+.+使用base64加密之后的playload+.+使用HS256算法加密,同时secret加盐处理

    2.Browsable API页面认证

    1.源码

    'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.BasicAuthentication'
        ]

    2.说明

    BasicAuthentication:基本的用户密码认证

    SessionAuthentication:session会话认证

    SessionAuthentication和BasicAuthentication二者缺一不可,相辅相成,我们也可以在此基础上增加别的认证,如:token认证、微信/QQ第三方认证、LADP认证

    在authentication.py模块中,除了上面这两种,还有其它的认证方式可供选择:

    3.指定视图下认证

    authenticcation_classes = []  # 列表中添加对应的认证方式

    一般不需要指定视图下进行认证,往往一个项目下只会使用一种认证方式

    4.创建超级管理员

    命令行

    python manage.py createsuperuser --username USERNAME --email EMAIL

    5.添加路由

    这里提供的是一种前后端不分离的登录,后面会舍弃掉

    在全局下的urls.py中添加如下代码

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/', include('rest_framework.urls'))
    ]

    我们可以去看看rest_framework下的urls.py

    配置了之后就已经提供了登录和登出的接口

    6.登录

    2.JWT认证

    1.jwt实现原理

    1.安装jwt

    pip install -i https://pypi.douban.com/simple pyjwt

    2.引入jwt

    import jwt

    3.指定header和playload

    header一般不需要指定,使用默认值即可

    指定后端需要存放的一些非敏感信息

    playload = {
        'username': '小公瑾',
        'age': 18
    }

    3.服务端创建token令牌

    token = jwt.encode(playload, key='user')  # key由服务器来规定

    4.服务端对前端用户传递的token进行解密

    res = jwt.decode(token, key='user')

    2.drf的token认证实现方法

    1.安装djangorestframework-jwt

    pip install -i https://pypi.douban.com/simple djangorestframework-jwt

    2.全局配置指定JWT Token认证

    一定要注意列表是有优先级的,需要把该认证放到第一个位置

    REST_FRAMEWORK = {
        # 认证方式
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.BasicAuthentication'
        ]
    }

    3.根路由配置user模块

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('user/', include('user.urls'))
    ]

    4.user子模块下添加路由

    from django.urls import path
    from rest_framework_jwt.views import obtain_jwt_token
    
    urlpatterns = [
        path('login/', obtain_jwt_token)
    ]

    5.验证结果

    6.重写jwt_response

    1).重写jwt_response_payload_handler

    def jwt_response_payload_handler(token, user=None, request=None):
    
        return {
            'user_id': user.id,
            'username': user.username,
            'token': token
        }

    2).注册重写的方法

    将rest_framework_jwt中的全局配置进行覆盖,源码配置如下:

    3).在全局配置中重写配置

    JWT_AUTH = {
        'JWT_RESPONSE_PAYLOAD_HANDLER':
        'utils.jwt_handler.jwt_response_payload_handler'
    }

    7.验证结果

    8.其它配置和说明

    1).其它接口认证

    • 前端用户访问一些需要认证之后的接口,那么默认需要在请求头中携带参数
    • 请求key默认为Authorization,值为前缀+空格+token值,如:
    JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhemF6aWUiLCJhdWQiOiJ1c2VycyIsImlhdCI6MTU5NTY3NTA1NiwiZXhwIjoxNTk2Mjc5ODU2LCJ1c2VyX2lkIjozMDI3NTQxfQ.vJPcwpw4_WBLGBkXO3SUPbyfgDzk4S3FwWzJrCtvhwA

    2).修改token过期时间

    覆盖rest_framework_jwt配置

    import datetime
    
    JWT_AUTH = {
        'JWT_RESPONSE_PAYLOAD_HANDLER':
        # token过期时间默认为300秒,这里可以自定义
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    }

    二、授权

    1.源码

    'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.AllowAny',
        ]

    2.说明

    源码中只提供了AllowAny的授权,它表示不限制任何权限,一般情况下,这种授权不会满足要求,我们可以看看permissions.py模块下提供的其它授权

     AllowAny:任意权限

    IsAuthenticated:允许登录后拥有权限

    IsAdminUser:管理员权限

    IsAuthenticatedOrReadOnly:未登录下只允许浏览

    3.指定视图下权限

    permission_classes = [permissions.AllowAny]

    permissions需要引入

    from rest_framework import permissions

     

  • 相关阅读:
    Android 重写系统Crash处理类,保存Crash信息到SD卡 和 完美退出程序的方法
    LeetCode第二十四题-交换链表中节点值
    LeetCode第二十三题-合并n个有序链表
    LeetCode第二十二题-创建n对括号
    LeetCode第二十一题-对两个有序链表排序
    LeetCode第二十题-有效的括号
    LeetCode第十九题-链表节点的删除
    LeetCode第十八题-四数之和
    LeetCode第十七题-电话号码的字母组合
    LeetCode第十六题-找出数组中三数之和最接近目标值的答案
  • 原文地址:https://www.cnblogs.com/xiaogongjin/p/13377222.html
Copyright © 2020-2023  润新知