首页 > 其他分享 >drf-jwt、simplejwt的使用

drf-jwt、simplejwt的使用

时间:2023-04-24 20:55:18浏览次数:44  
标签:name jwt rest framework token simplejwt import drf

1.接口文档

# 前后端分离
	-我们做后端,写接口
    -前端做前端,根据接口写app,pc,小程序
    
    -作为后端来讲,我们很清楚,比如登录接口  /api/v1/login/---->post---->username,password 编码方式json----》返回的格式  {code:100,msg:登录成功}
    
    
    -后端人员,接口写完,一定要写接口文档
    
    
# 接口文档如何编写
	1 使用word,md 编写接口文档
	2 使用第三方平台,编写我们的接口文档(非常多)---》收费
    	-https://www.showdoc.com.cn/item/index
	3 公司自己使用第三方开源的搭建的---》Yapi ---》你如果想自己搭建
    	-https://zhuanlan.zhihu.com/p/366025001 
            
	4 使用drf编写的接口,可以自动生成接口文档
    	-swagger---》drf-yasg---》官方推荐使用
        -coreapi----》咱们讲
    
    
# 使用coreapi自动生成接口文档步骤
	- 1 安装 
    - 2 配置路由
        from rest_framework.documentation import include_docs_urls
        path('docs/', include_docs_urls(title='xx项目接口文档')),
    -3 在视图类,方法上,写注释即可
    	-在类上加注释
        -在类的方法上加注释
        -在序列化类或表模型的字段上加  help_text,required。。。。
    
    
    -4 配置文件配置
    	REST_FRAMEWORK = {
     		'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',

    	}
        
        
   -5 访问地址:http://127.0.0.1:8000/docs
# 1    
    
    
# 接口文档,需要有的东西
	-描述
    -地址
    -请求方式
    -请求编码格式
    -请求数据详解(必填,类型)
    -返回格式案例
    -返回数据字段解释
    -错误码

2.jwt介绍和原理

1.在用户注册或登陆后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而是使用Json Web Token(本质就是token)认证机制。
"""
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
"""

2.JWT的构成:
	JWT是一段字符串,由三段信息构成,将这三段信息文本用.连接在一起,就构成了JWT字符串,例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
第一段信息:
	头(header),声明加密算法和类型:
import base64
import json
res = base64.b64decode('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9')
print(json.loads(res))  # {'alg': 'HS256', 'typ': 'JWT'}      

第二段信息:
	荷载(payload):存放有效信息的地方:过期时间、签发时间、用户id、用户名等。
标准中注册的声明 (建议但不强制使用) :

iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避时序攻击。
            
第三段信息:
	签名(signature),这个方式需要base64加密后的header和base64加密后的payload用.连接起来组成字符串,然后通过header中声名的加密方式进行加盐secret组合加密,就构成了jwt的第三部分。
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ(得到的仅是第三部分。
"""
注意:secret是保存在服务端当中的,并且服务端只有一个secret,也就是所有的用户加密的秘钥都是相同的,jwt的签发也是在服务端发生,secret就是用来进行jwt的签发和jwt的验证,所以这是服务端的私钥,任何时候都不应该泄露出去。泄露出去代表客户端可以自己签发jwt了。
"""  

3.drf-jwt的快速使用

1.django+drf平台开发jwt有两个模块:
djangorestframework-jwt(用的时间比较久了)
djangorestframework-simplejwt(公司使用较多 )

2.djangorestframework-jwt使用:
安装:
	pip install djangorestframework-jwt
使用:
	默认签发token都是根据auth_user表签发的,如果自定义表格,需要自己手动编写代码。
代码:
# 导入模块
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('login/',obtain_jwt_token) # 添加路由,此后向/login/这个路由发送post申请,并且携带{"username":xxx,"password":xxx}就可以登陆获得token
]
并且在auth_user中插入一条用户数据。

4.定制返回信息

此后,基于auth的User表签发token就可以不用自己写了,但是登陆接口返回对的格式只有token,不符合公司规定。通过以下方式添加信息:
在app中建一个py文件:jwt_response_payload_handler,在里面新建一个函数:jwt_response_payload_handler。
def jwt_response_payload_handler(token,user=None,request=None):
    return {
        'code':100,
        'msg':'登录成功',
        'token':token,
        'username':user.username
    }
在settings.py中配置:
JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.jwt_response_payload_handler.jwt_response_payload_handler',
}

5.jwt认证类

很多接口需要登陆以后才能访问,我们需要在视图类上加一个认证类和一个权限类。
代码:
views.py:
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated

class BookView(ViewSetMixin,APIView):
    # 首先需要加两个认证类:
    authentication_classes = [JSONWebTokenAuthentication]  # 校验是否携带token
    permission_classes = [IsAuthenticated]  # 校验是否登陆
    def list(self,request):
        """
        查询所有图书接口
        """
        books = Book.objects.all()
        paginator = CommonLimitOffsetPagination()
        page = paginator.paginate_queryset(books,request,self)
        if page is not None:
            serializer = BookSerializer(instance=page,many=True)
            return Response({
                'total':paginator.count,
                'next':paginator.get_next_link(),
                'previous':paginator.get_previous_link(),
                'results':serializer.data
            })
 然后在发送get请求时,需要在请求头中携带键值对:Authorization:jwt 空格 token,即可发送成功。

6.simplejwt使用

1.djangorestframework-simplejwt是一个模块,使用前要先下载。

2.settings.py需要配置以下内容:
INSTALLED_APPS = [
'rest_framework',
]
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',  # 使用rest_framework_simplejwt(token)验证身份
        'rest_framework.authentication.SessionAuthentication',  # 基于用户名密码认证方式
        'rest_framework.authentication.BasicAuthentication'  # 基于Session认证方式
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated'  # 默认权限为验证用户
    ],
}

import datetime
SIMPLE_JWT = {
    # token有效时长
    'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=30),
    # token刷新后的有效时间
    'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1),
}

urls.py:
from django.contrib import admin
from django.urls import path,include
from app01 import views

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
    TokenVerifyView
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/auth/', include('rest_framework.urls', namespace='rest_framework')),
    # 获取Token的接口
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    # 刷新Token有效期的接口
    path('api/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    # 验证Token的有效性
    path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
    path('books/',views.BookView.as_view())
    ]

models.py:
from django.db import models

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def publish_detail(self):
        return {'name': self.publish.name,'addr':self.publish.addr}

    def author_list(self):
        l = []
        for author_obj in self.authors.all():
            l.append({'name':author_obj.name,'phone':author_obj.phone})
        return l

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)

class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.CharField(max_length=11)

serializer.py:
from rest_framework import serializers
from app01.models import Book
from rest_framework.exceptions import ValidationError

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish', 'authors', 'publish_detail', 'author_list']
        extra_kwargs = {
            'name': {'max_length': 8},
            'publish_detail': {'read_only': True},
            'author_list': {'read_only': True},
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }

        def validate_name(self, name):
            if name.startswith('s'):
                raise ValidationError('书名不能以s开头')
            else:
                return name
views.py:
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin,ListModelMixin
from rest_framework.permissions import IsAuthenticated
from .models import Book
from .serializer import BookSerializer

class BookView(GenericAPIView,ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # simplejwt只需要配置权限类
    permission_classes = [IsAuthenticated]
    def get(self,request):
        return self.list(request)
    
3.执行数据库迁命令:makemigrate、migrate。再执行创建管理员操作:createsuperuser。
      
4.获取token:
路由:http://127.0.0.1:8000/api/token/。获取路由使用post请求并且需要在body当中携带用户名和密码。获取到的token有两个,一个是refresh,一个是access。refresh是用来刷新的,accrss是用来查数据的。

5.刷新token:
路由:http://127.0.0.1:8000/api/refresh/。刷新token时需要携带老的refresh token。

6.查数据:
路由:http://127.0.0.1:8000/books/。由于在视图函数中已经配置了权限类,所以token校验通过之后才会走。并且需要在请求头当中携带token,携带格式为:{'Authorization':'Bearer token字符串'}

标签:name,jwt,rest,framework,token,simplejwt,import,drf
From: https://www.cnblogs.com/ERROR404Notfound/p/17107338.html

相关文章

  • SpringSecurity从入门到精通:用户密码加密存储&铺垫只是jwt工具类使用
    用户密码加密存储    铺垫只是jwt工具类使用 ......
  • python jwt token使用
    官网https://pyjwt.readthedocs.io/en/latest/index.html#官网https://pyjwt.readthedocs.io/en/latest/index.html#我们在jwt.encode函数中使用了三个参数:#1)第一个是payload,主要用来存放有效的信息,例如用户名,过期时间等想要传递的信息。payload字典内部官方指定有指定ke......
  • drf之请求request与response
    目录Request可解析编码格式定制传入数据类型格式方法一,使用parser_classes定制方法二,使用settings.py配置优先级说明Response方法一,在类中定义Response返回格式方法二,在settings.py中定义返回格式优先级说明Responseinit可以传入的参数Request可解析编码格式request可以解析三......
  • springboot集成JWT token验证
    登录模式基于session登录基于session的登录(有回话状态),用户携带账号密码发送请求向服务器,服务器进行判断,成功后将用户信息放入session,用户发送请求判断session中是否有用户信息,有的话放行,没有的话进行拦截,但是考虑到时App产品,牵扯到要判断用户的session,需要sessionID,还要根据sess......
  • drf之ModelSerializer
    目录简介语法示例使用Meta进行定义在Meta类外进行定义简介与表做强关联,之后不需要再写create与update函数了官网:https://www.django-rest-framework.org/api-guide/serializers/语法有多种写法,局部钩子与全局钩子是一样的class类名(serializers.ModelSerializer)#......
  • 若依jwt
    Authorization:BearereyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImRjMDRhOWE2LWE2YTgtNDA1My04MmU4LTRmNmRkMjdjYTA3NCJ9.8ZaOBAnKZ2acfBqZcHvsdRL9DYTaKxeGuyDUglt74HfMuw918p7mdj_uwyeKxA3xMcxi5WNKTOlda33xJ2mX3Alogin_tokens:dc04a9a6-a6a8-4053-82e8-4f6dd27ca07......
  • DRF的filter组件
    DRF的Filter组件如果某个API需要传递一些条件进行搜索,其实就在是URL后面通过GET传参即可,例如:/api/users?age=19&category=12在drf中filter组件可以支持条件搜索。1.自定义filter#models.pyfromdjango.dbimportmodelsclassRole(models.Model):"""角色表"""......
  • 铺垫知识jwt工具类使用、登录接口实现细节分析和代码实现、测试接口
    铺垫知识jwt工具类使用JWT工具类:JWTUtilpublicstaticvoidmain(String[]args)throwsException{//加密Stringjwt=createJWT("2123");System.out.println(jwt);//解密Claimsclaims=parseJWT("eyJhbGciOiJIUzI1......
  • session,cookie,token,jwt
    cookie,session,token,jwtCookiecookie是为了解决HTTP在状态管理上的不足,HTPP是无状态协议。目的是让服务端知道客户端的身份。cookie储存在客户端。Sessionsession是记录服务器和客户端会话状态的机制session是基于cookie实现的,session存储在服务器端,sessionid储存在客户端的co......
  • drf之多表关联反序列化保存read_only与write_only
    目录read_only与write_only示例假如前端传入了一组数据:{name:'赛尔达传说:王国之泪',price:350,publish:1,authors:[1,2]}如上:publish按id传入,authors也按id传入。read_only与write_onlyread_only用于序列化write_only用于反序列化这两个是字段参数示例#......