jwt drf authentication framework, as well as custom authentication jwt

0909 self-summary

In the framework of jwt drf

A. Mounting module

官方:http://getblimp.github.io/django-rest-framework-jwt/

He is a third-party open source projects

安装:pip install djangorestframework-jwt

Use 自带set a good jwt

from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('login/', obtain_jwt_token),
]
'''
path('login/', obtain_jwt_token)其实相当于path('login/', ObtainJSONWebToken.as_view())
因为我们之间进源码可以看到
obtain_jwt_token = ObtainJSONWebToken.as_view()     #获得
refresh_jwt_token = RefreshJSONWebToken.as_view()   #刷新
verify_jwt_token = VerifyJSONWebToken.as_view()     #验证
'''

Test Interface: post request

"""
postman发生post请求

接口:http://api.luffy.cn:8000/user/login/

数据:
{
    "username":"admin",
    "password":"admin"
}
"""

II. Works

"""
jwt:json web tokens 采用json格式在web上传输的 认证字符串

jwt字符串:头.载荷.签名

头:公司基本信息、项目组基本信息、常规加密算法名
载荷:用户信息、过期时间
签名:头、载荷、秘钥

{头信息字典,采用base64加密算法}.{载荷信息字典,采用base64加密算法}.{头加密串、载荷加密串、服务器秘钥,采用hs256加密算法}

base64是可逆加密
hash256是不可逆加密
我们一般只会将账号信息,过期时间放载荷里面,一般把密码什么重要信息丢签名里面
"""

III. Three certification

session authentication

系统自带的

rest_framework.authentication.SessionAuthentication
Ajax authenticated request:
Cookie to be carried sessionid, csrftoken, to be carried in the request header x-csrftoken

jwt certification

第三方

Authentication and session distinction he did not have to check the sessionidtable, as long as the check userlist on it

rest_framework_jwt.authentication.JSONWebTokenAuthentication
Ajax authenticated request:
the request header to be carried authorization, token blank value jwt

Based jwt, other

自定义

1) certified custom class that inherits BaseAuthentication (or subclasses), override the authenticate
2) completed the authenticate

  • Get the certification mark auth

  • Anti parse user user

  • Two steps before failure returns None => visitors

  • Two steps before successful return user, auth => User Login

    : If an exception is thrown in a branch, directly define failure => illegal users

IV. Custom certification, based on jwt

其实就是在jwt的源码基础上进行相关的修改

The simplest modification

from rest_framework.exceptions import AuthenticationFailed
import jwt
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.authentication import jwt_decode_handler

from rest_framework.authentication import BaseAuthentication
def authenticate(self, request):
    auth = 从request中得到
    user = 从auth中得到
    if not user:
        return None
    return user, auth

如果我们自定制了一个权限我们进行全局设置必须自己在setting把这个函数加进去

'DEFAULT_AUTHENTICATION_CLASSES': [
    '我们自定义认证函数的对象',
],

我们做局部设置就在我们自定义的类中添加

authentication_classes = [我们自定义认证函数的对象]

V. custom permissions related

也是改源码

"""
系统:
1)AllowAny:允许所有用户,校验方法直接返回True
2)IsAuthenticated:只允许登录用户
    必须request.user和request.user.is_authenticated都通过
3)IsAuthenticatedOrReadOnly:游客只读,登录用户无限制
    get、option、head 请求无限制
    前台请求必须校验 request.user和request.user.is_authenticated
4)IsAdminUser:是否是后台用户
    校验 request.user和request.user.is_staff    is_staff(可以登录后台管理系统的用户)
    

自定义:基于auth的Group与Permission表
1)自定义权限类,继承BasePermission,重写has_permission
2)has_permission中完成
    拿到登录用户 user <= request.user
    校验user的分组或是权限
    前两步操作失败 返回False => 无权限
    前两步操作成功 返回True => 有权限
"""
#根据用户分组信息设置相关权限
from rest_framework.permissions import BasePermission

class AdminPermission(BasePermission):
    # 继承BasePermission,重写has_permission
    def has_permission(self, request, view):
        # 有权限,返回True
        # 无权限,返回False
        user = request.user
        if not user:
            return False
        # 用户是 管理员 分组 (管理员分组是Group表中的一条自定义记录)
        if not user.groups.filter(name='管理员'):
            return False
        # 登录的用户必须是自定义管理员分组成员
        return True

如果我们自定制了一个权限全局设置我们必须自己在setting把这个函数加进去

'DEFAULT_PERMISSION_CLASSES': [
    '我们自定义权限函数的路径',
],

我们做局部设置就在我们自定义的类中添加

permission_classes = [我们自定义认证函数的对象]

VI. Custom settings visits

"""
系统:
1)AnonRateThrottle:对同一IP游客的限制
2)UserRateThrottle:对同一IP登录用户的限制
必须在settings.py中
'DEFAULT_THROTTLE_RATES': {
    'user': '10/min',  # 登录的用户一分钟可以访问10次
    'anon': '3/min',  # 游客一分钟可以访问3次
}
在视图类中:
class TempAPIView(APIView):
    ...
    throttle_classes = [AnonRateThrottle, UserRateThrottle]
    
    

自定义:基于auth的Group与Permission表
1)自定义频率类,继承SimpleRateThrottle,重写get_cache_key,明确scope
    SimpleRateThrottle已经帮我们实现了 allow_request、wait
2)scope与settings.py的DEFAULT_THROTTLE_RATES配合使用
3)get_cache_key中完成
    拿到限制信息 ident <= request中获取
    没有限制信息 返回None => 不限制
    有限制信息 返回限制信息字符串 => 有限制
"""

Custom frequency categories: one minute a phone number once only allow access to the interface

from rest_framework.throttling import SimpleRateThrottle

class ThreeMinRateThrottle(SimpleRateThrottle):
    scope = 'sms'
    def get_cache_key(self, request, view):
        # 对手机号频率限制
        ident = request.data.get('mobile')
        if not ident:  # 为发现限制条件,返回None代表不进行频率限制
            return None
        return self.cache_format % {
            'scope': self.scope,
            'ident': ident
        }
# settings.py 
'DEFAULT_THROTTLE_RATES': {
    'user': '10/min',  # 登录的用户一分钟可以访问10次 如果是
    'anon': '3/min',  # 游客一分钟可以访问3次
    'sms': '1/min',  #是我们自定义的,默认只提供user以及anon
}
在视图层
class UserListAPIView(ListAPIView):
    throttle_classes = [我们自定义的方法路径]

Source code is in a period of time of about

    def parse_rate(self, rate):
        """
        Given the request rate string, return a two tuple of:
        <allowed number of requests>, <period of time in seconds>
        """
        if rate is None:
            return (None, None)
        num, period = rate.split('/')
        num_requests = int(num)
        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
        return (num_requests, duration)

这里我们可以看出来是先/进行字符串切分然后取第一个字母We do not necessarily use all here min for minutes, is just beginning to m

VII. Global Settings name of the effective time and jwt

import datetime
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=30000),#d到期时间
    'JWT_AUTH_HEADER_PREFIX': 'TOKEN',  #我们传参数的时候开头自定义内容,注意点这里必须与下面的token中以宫格隔开
}

源码中为

USER_SETTINGS = getattr(settings, 'JWT_AUTH', None)  #他是通过JWT_AUTH这个名字
......
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
'JWT_AUTH_HEADER_PREFIX': 'JWT',  系统默认以jwt开头

Guess you like

Origin www.cnblogs.com/pythonywy/p/11494174.html