DRF之simple-jwt使用

simple-jwt使用

# 使用simple-jwt 快速体验  pip install djangorestframework-simplejwt

# python manage.py createsuperuser
'''创建超级用户是为了方便管理 Django 的后台管理界面,而 simple-jwt 的使用则是为了在 Django REST Framework 中实现 JWT 认证和用户身份验证。这两个步骤是相互独立的,但通常都需要在你的项目中进行。'''

# 用户名: admin   
# 电子邮件地址: 333@qq.com
# 密码: 123123

	- 登陆签发:默认使用auth的user表--》创建个用户--》能登录了
    	路由:   登陆接口了 
        path('login/', token_obtain_pair), 
        # 127.0.0.1:8080/app01/login-->post--》用户名密码就能登陆
    - 认证
    class UserTokenView(GenericViewSet, mixins.CreateModelMixin):
        # 必须登陆后才能新增
        authentication_classes = [JWTAuthentication]
        permission_classes = [IsAuthenticated]

创建一个超级管理员

image-20240418221507413

  • from rest_framework_simplejwt.views import token_obtain_pair
# 登陆接口
from rest_framework_simplejwt.views import token_obtain_pair

from three.views import BookViewSet, UserTokenView, TeyView
# 自动生成路由
from rest_framework.routers import SimpleRouter, DefaultRouter
from django.urls import path, include

# 2 实例化得到对象
# router = SimpleRouter()
router = DefaultRouter()
# 3 执行对象的方法
router.register('User', UserTokenView, 'User')


urlpatterns = [
    path('login/', token_obtain_pair),
    path('try/', TeyView.as_view()),

]
# 5 把自动生成的路由,放到 urlpatterns中
urlpatterns += router.urls
# 序列化类
from rest_framework import serializers
from .models import Book,User,UserToken


#
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
#---------------------------------- 
from rest_framework import mixins
# 认证
from rest_framework_simplejwt.authentication import JWTAuthentication

from rest_framework.permissions import IsAuthenticated


class UserTokenView(GenericViewSet, mixins.CreateModelMixin):
	# 获取表中信息
    queryset = Book
    # 序列化类
    serializer_class = BookSerializer
    # 必须登陆之后才能新增
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]  

使用步骤

  • 先登陆接口复制

  • "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzEzNDUwMjY1LCJpYXQiOjE3MTM0NDk5NjUsImp0aSI6ImIyNWFjNmI3NDQ3ZjQ3NzFhYjViYjM4ZDYzMjhiNTkzIiwidXNlcl9pZCI6MX0.xcqKK-YY2fpMkYKre6VpUOfmWdr2V_i-XL4R5pkOlCE"
    
  • http://127.0.0.1:8300/three/User/ 这个接口header key:Authorization , vlaue:access的值

image-20240418223005100

image-20240418223053987

image-20240418222931763

【 1 】simple-jwt配置文件

# 用户模型        # 应用程序.表名
AUTH_USER_MODEL = "one.UserInfo"

# settings.py配置文件
import datetime
SIMPLE_JWT = {
    # token有效时长
    'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=30),
    # token刷新后的有效时间
    'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1),
}
  • accessToken:用户获取数据权限
  • refreshToken:用来获取新的accessToken

# 用户模型        # 应用程序.表名
AUTH_USER_MODEL = "one.UserInfo"

# JWT配置
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),  # Access Token的有效期
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),  # Refresh Token的有效期
    
    # 对于大部分情况,设置以上两项就可以了,以下为默认配置项目,可根据需要进行调整
    
    # 是否自动刷新Refresh Token
    'ROTATE_REFRESH_TOKENS': False,  
    # 刷新Refresh Token时是否将旧Token加入黑名单,如果设置为False,则旧的刷新令牌仍然可以用于获取新的访问令牌。需要将'rest_framework_simplejwt.token_blacklist'加入到'INSTALLED_APPS'的配置中
    'BLACKLIST_AFTER_ROTATION': False,  
    'ALGORITHM': 'HS256',  # 加密算法
    'SIGNING_KEY': settings.SECRET_KEY,  # 签名密匙,这里使用Django的SECRET_KEY
    # 如为True,则在每次使用访问令牌进行身份验证时,更新用户最后登录时间
    "UPDATE_LAST_LOGIN": False, 
    # 用于验证JWT签名的密钥返回的内容。可以是字符串形式的密钥,也可以是一个字典。
    "VERIFYING_KEY": "",
    "AUDIENCE": None,# JWT中的"Audience"声明,用于指定该JWT的预期接收者。
    "ISSUER": None, # JWT中的"Issuer"声明,用于指定该JWT的发行者。
    "JSON_ENCODER": None, # 用于序列化JWT负载的JSON编码器。默认为Django的JSON编码器。
    "JWK_URL": None, # 包含公钥的URL,用于验证JWT签名。
    "LEEWAY": 0, # 允许的时钟偏差量,以秒为单位。用于在验证JWT的过期时间和生效时间时考虑时钟偏差。
    # 用于指定JWT在HTTP请求头中使用的身份验证方案。默认为"Bearer"
    "AUTH_HEADER_TYPES": ("Bearer",), 
    # 包含JWT的HTTP请求头的名称。默认为"HTTP_AUTHORIZATION"
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", 
     # 用户模型中用作用户ID的字段。默认为"id"。
    "USER_ID_FIELD": "id",
     # JWT负载中包含用户ID的声明。默认为"user_id"。
    "USER_ID_CLAIM": "user_id",
    
    # 用于指定用户身份验证规则的函数或方法。默认使用Django的默认身份验证方法进行身份验证。
    "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",
    #  用于指定可以使用的令牌类。默认为"rest_framework_simplejwt.tokens.AccessToken"。
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    # JWT负载中包含令牌类型的声明。默认为"token_type"。
    "TOKEN_TYPE_CLAIM": "token_type",
    # 用于指定可以使用的用户模型类。默认为"rest_framework_simplejwt.models.TokenUser"。
    "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",
    # JWT负载中包含JWT ID的声明。默认为"jti"。
    "JTI_CLAIM": "jti",
    # 在使用滑动令牌时,JWT负载中包含刷新令牌过期时间的声明。默认为"refresh_exp"。
    "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
    # 滑动令牌的生命周期。默认为5分钟。
    "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
    # 滑动令牌可以用于刷新的时间段。默认为1天。
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
    # 用于生成access和刷refresh的序列化器。
    "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
    # 用于刷新访问令牌的序列化器。默认
    "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
    # 用于验证令牌的序列化器。
    "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
    # 用于列出或撤销已失效JWT的序列化器。
    "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
    # 用于生成滑动令牌的序列化器。
    "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
    # 用于刷新滑动令牌的序列化器。
    "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}

【 2 】jwt定制登陆的返回格式

这些的前提条件就是要先写一个登陆的接口

  • path('login/', token_obtain_pair)``token_obtain_pair是Django REST Framework SimpleJWT提供的系统自带的用于获取访问令牌(access token)和刷新令牌(refresh token)的登录认证接口。
# 登陆接口
from rest_framework_simplejwt.views import token_obtain_pair

from three.views import  UserTokenView 
# 自动生成路由
from rest_framework.routers import SimpleRouter, DefaultRouter
from django.urls import path, include

# 2 实例化得到对象
# router = SimpleRouter()
router = DefaultRouter()
# 3 执行对象的方法

router.register('User', UserTokenView, 'User')


urlpatterns = [
    path('login/', token_obtain_pair),

]
# 5 把自动生成的路由,放到 urlpatterns中
urlpatterns += router.urls

# views.py
from rest_framework import mixins
# 认证
from rest_framework_simplejwt.authentication import JWTAuthentication

from rest_framework.permissions import IsAuthenticated


class UserTokenView(GenericViewSet, mixins.CreateModelMixin):
    # 获取表中信息
    print(11111)
    queryset = Book
    # 序列化类
    serializer_class = CommonTokenserializer
    print(serializer_class)
    # <class 'three.serial.BookSerializer'>
    # 必须登陆之后才能新增
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
# 写一个序列化类。继承TokenObtainPairSerializer —— >> 重写validate方法。
class CommonTokenserializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        """
        自定义返回的格式
        """
        # 获取父类的原始数据
        old_data = super().validate(attrs)
        data = {'code': 100,
                'msg': '登录成功成功',
                'username': self.user.username,
                # 刷新令牌
                'refresh': old_data.get('refresh'),
                # 访问令牌
                'access': old_data.get('access')
                }
        return data

  • 配置文件

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

    "TOKEN_OBTAIN_SERIALIZER": "three.serial.CommonTokenserializer"
}

【 3 】 定制payload格式

  • 这个跟登陆返回格式大致一样

  • 序列化类

  1. CommonTokenObtainSerializer 类继承自 TokenObtainPairSerializer,这意味着它继承了 TokenObtainPairSerializer 类的所有属性和方法,并且可以在此基础上进行定制化。
  2. get_token(cls, user) 方法是一个类方法,用于获取令牌。它首先调用父类的 get_token 方法来获取令牌对象,然后将用户的用户名添加到令牌中,并返回更新后的令牌对象。
  3. validate(self, attrs) 方法是一个局部钩子,用于验证输入数据。在这个方法中,首先调用父类的 validate 方法来验证输入的属性,并获取到验证后的结果。然后,从验证结果中获取令牌的 refreshaccess 属性,并将其与用户的用户名一起包装成一个字典返回给客户端。这个方法的主要作用是在用户登录成功后返回额外的信息,比如用户名和自定义的消息。
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer


class CommonTokenserializer(TokenObtainPairSerializer):

    @classmethod
    def get_token(cls, user):
        # super() --> 代指父类的对象
        # 对象调用类的绑定方法,会自动把对象的类传入。
        token = super().get_token(user)
        token['name'] = user.username
        return token

    # 局部钩子
    def validate(self, attrs):
        dict_res = super().validate(attrs)
        data = {
            'code': 1000,
            'message': '登陆成功',
            # 获取用户信息
            'username': self.user.username,
            'refresh': dict_res.get('refresh'),
            'access': dict_res.get('access')
        }
        return data
SIMPLE_JWT = {
"TOKEN_OBTAIN_SERIALIZER": "three.serial.CommonTokenserializer"
}

【 4 】多方式登陆

  • 扩写auth的user表—》加入mobile字段
    -注意:
    -之前迁移过–》auth的user表已经生成了,就不能扩展写
    -方案一: 创建新项目,从头做
    -方案二:删库,删除迁移记录(咱们自己app和auth和admin)
    -以后如果要扩写auth的user表,必须在迁移之前就定好,写好

  • 编写登陆接口

这里建议直接删除省事还可以直接就是要我们原本定义的User表中的数据。

# mdoels.py
from django.db import models
from django.contrib.auth.models import AbstractUser


class User(models.Model):
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)
    phone = models.CharField(max_length=11)
    email = models.EmailField(unique=True)  # 添加 email 字段
    user_type = models.IntegerField(choices=((1, '注册用户'), (2, '普通管理员'), (3, '超级管理员')), default=1)

要么就是使用在数据迁移之后出现的UserInfo表

UserInfo表它继承自Django提供的 AbstractUser 模型。AbstractUser 是 Django 内置的用户模型,它包含了常见的用户属性,如用户名、密码和电子邮件地址等 。 我们只需要在这个基础上在models.py文件当添加一个phone字段就可以了。

from django.db import models
from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    phone = models.CharField(max_length=11)
    # 这里可以添加额外的字段,不需要再次定义 username、password 和 email 字段
  • image-20240422203508439

  • urls.py

  • http://127.0.0.1:8110/one/user/login/

from django.urls import path, include
# 登陆接口
from rest_framework_simplejwt.views import token_obtain_pair
# 自动生成路由
from rest_framework.routers import SimpleRouter, DefaultRouter
from one.views import UserJWTokenView,UserJWTOneView,PublishViews

# 2 实例化得到对象
# router = SimpleRouter()
router = DefaultRouter()
# 多方式登陆
router.register('user', UserJWTokenView, 'user')
# 自定义用户表,手动签发和认证
router.register('user1', UserJWTOneView, 'user1')
# 先登陆在访问
router.register('publish',PublishViews , 'publish')

urlpatterns = [
    # 系统自带的登陆接口
    path('login/', token_obtain_pair),
    # path('api/v1',include(router.urls))/
]

# 5 把自动生成的路由,放到 urlpatterns中
urlpatterns += router.urls
  • views.py

from rest_framework.viewsets import GenericViewSet
# 限制响应方法
from rest_framework.decorators import action
from .serializer import LoginJWTSerial, LoginJWTOneSerial
# 响应
from rest_framework.response import Response

# 认证类
from .authent import JWTOurSerial


class UserJWTokenView(GenericViewSet):
    serializer_class = LoginJWTSerial

    @action(methods=['POST'], detail=False)
    def login(self, request, *args, **kwargs):
        # 正常逻辑:取出手机号 / 用户名 / 邮箱 + 密码 - -》去数据校验 - -》校验通过 -->签发token - -》返回给前端
        # 现在直接在序列化定义
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():  # 执行 三层认证
            # 校验通过:会把user,access和refresh都放到序列化类对象中--》返回给前端、
            # 现在在视图类中----》有个序列化类--》把视图类中变量给序列化类---》序列化类的变量给视图类--》借助于context给[字典]
            refresh = serializer.context.get('refresh')
            access = serializer.context.get('access')
            return Response({'code': 100, 'msg': '登录成功', 'refresh': refresh, 'access': access})
        else:
            return Response({'code': 101, 'msg': serializer.errors})
  • 序列化类

# 序列化模块
from rest_framework import serializers
import re

from rest_framework_simplejwt.tokens import RefreshToken

from one.models import User
# 异常捕获
from rest_framework.exceptions import ValidationError


# 多方式登陆
class LoginJWTSerial(serializers.Serializer):
    # 判断是用户名、手机号、邮箱等等
    # 对用户进行序列化
    username = serializers.CharField()
    password = serializers.CharField()

    def _get_user(self,attrs):
        # 【1】校验用户
        username = attrs.get('username')
        password = attrs.get('password')
        # 我们要去数据库  查询用户 ---> username 可能是 用户名、手机号、邮箱
        # 所以我们要在登陆的时候进行检验(使用正则)
        if re.match(r'^1[3-9][0-9]{9}$', username):
            # 手机号
            user = User.objects.filter(phone=username).filter()
        elif re.match(r'^.+@.+$',username):
            user = User.objects.filter(email=username).filter()
        else:
            user = User.objects.filter(username=username).filter()
        # 校验user是否在User表中是否存在
        if user and user.first().password == password:
            print(user)

            return user.first()
        else:
            raise ValidationError('用户名或者密码错误!!!')

    def validate(self, attrs):
    # 取出 手机号/用户名/邮箱+密码--》数据库校验--》校验通过签发 access和refresh,放到context中
        user = self._get_user(attrs)
        # 验证token
        token = RefreshToken.for_user(user)
        self.context['access'] = str(token.access_token)
        self.context['refresh'] = str(token)
        return attrs  # 不返回不行:因为源码中校验了是否为空--》

image-20240422212317739

image-20240422212644103

image-20240422212804022

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzEzNzkyMzc2LCJpYXQiOjE3MTM3OTIwNzYsImp0aSI6IjllZmQxM2E5MDk2ZTQ0OGFhZjU5ODQ1OGNiOWFkMTRlIiwidXNlcl9pZCI6Mn0.uR1mUGDW703oQkbJhDedm3k8o1AiDGOsWCB4UVEXhvQ 

是一个 JSON Web Token(JWT)。JWT 通常由三部分组成,它们用点号 . 分隔开来:

  1. Header(头部):包含了该 JWT 使用的算法等信息。
  2. Payload(荷载):包含了实际的数据,比如用户的身份信息以及其他数据。
  3. Signature(签名):用于验证 JWT 的真实性,确保它没有被篡改过。

在你提供的 JWT 中,第一个逗号之前的部分就是头部,第二个逗号之前的部分是荷载,第三个逗号之后的部分是签名。

总结:

# 1 校验数据,放到序列化类的 validate中,而不放在视图类的方法中乐
# 2 视图类和序列化类直接交互变量
	serializer.context
    
# 3 user.check_password  必须是auth的user表,校验密码使用它


# 4 attrs必须返回值,返回空报错

# 5 视图类的方法校验失败的else中:也要return Response
# 6 如何签发token
token = RefreshToken.for_user(user)
self.context['access'] = str(token.access_token)
self.context['refresh'] = str(token)

【 5 】自定义用户表,手动签发和认证

  • urls.py

from django.urls import path, include
# 登陆接口
from rest_framework_simplejwt.views import token_obtain_pair
# 自动生成路由
from rest_framework.routers import SimpleRouter, DefaultRouter
from one.views import UserJWTOneView,PublishViews

# 2 实例化得到对象
# router = SimpleRouter()
router = DefaultRouter()
# 自定义用户表,手动签发和认证
router.register('user1', UserJWTOneView, 'user1')
# 先登陆在访问
router.register('publish',PublishViews , 'publish')

urlpatterns = [
    # 系统自带的登陆接口
    path('login/', token_obtain_pair),
    # path('api/v1',include(router.urls))/
]

# 5 把自动生成的路由,放到 urlpatterns中
urlpatterns += router.urls
  • views.py

class UserJWTOneView(GenericViewSet):
    serializer_class = LoginJWTOneSerial

    @action(methods=['POST'], detail=False)
    def login(self, request, *args, **kwargs):

        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():  # 执行 三层认证
            # 校验通过:会把user,access和refresh都放到序列化类对象中--》返回给前端、
            # 现在在视图类中----》有个序列化类--》把视图类中变量给序列化类---》序列化类的变量给视图类--》借助于context给[字典]
            refresh = serializer.context.get('refresh')
            access = serializer.context.get('access')
            return Response({'code': 200, 'msg': '登录成功', 'refresh': refresh, 'access': access})
        else:
            return Response({'code': 101, 'msg': serializer.errors})

# 登陆之后的测试 ----------------------------------------------------------
class PublishViews(GenericViewSet):

    authentication_classes = [JWTOurSerial]

    def list(self, request):
        return Response('查看成功!!!')
  • 序列化类

class LoginJWTOneSerial(serializers.Serializer):
    # 用户名
    username = serializers.CharField()
    password = serializers.CharField()

    def _get_user(self, attrs):
        # 1 校验用户
        username = attrs.get('username')
        password = attrs.get('password')
        user = User.objects.filter(username=username, password=password).first()
        # 校验用户是否
        if user:
            return user
        else:
            raise ValidationError('用户名或密码错误')

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = RefreshToken.for_user(user)
        self.context['access'] = str(token.access_token)
        self.context['refresh'] = str(token)
        return attrs

  • 自定义认证类

from rest_framework_simplejwt.authentication import JWTAuthentication
from .models import User
class JWTOurAuth(JWTAuthentication):
    def authenticate(self, request):
        # 取出用户携带的access---》放请求头中:Authorization
        token = request.META.get('HTTP_AUTHORIZATION')
        if token:
            # 校验token--》validated_token 返回的就是可以信任的payload
            validated_token = self.get_validated_token(token)
            user_id = validated_token['user_id']
            user = User.objects.filter(pk=user_id).first()
            return user, token
        else:
            raise AuthenticationFailed('请携带登录信息')
  • http://127.0.0.1:8110/one/user1/login/ POST
  • http://127.0.0.1:8110/one/publish/ GET

image-20240422213500579

  1. 序列化类 LoginJWTOneSerial
    • 定义了两个字段 usernamepassword,用于接收用户提交的用户名和密码。
    • _get_user 方法用于根据提交的用户名和密码查询用户,如果找到用户,则返回用户对象,否则抛出 ValidationError 异常。
    • validate 方法用于对提交的数据进行验证,调用 _get_user 方法验证用户,并使用 RefreshToken.for_user 方法为用户生成 JWT,将生成的 access token 和 refresh token 放入 context 中返回。
  2. 用户模型 User
    • 定义了用户的基本信息,包括用户名、密码、手机号、邮箱和用户类型等字段。
  3. 使用方式:
    • 用户可以通过 http://127.0.0.1:8110/one/user1/login/ 地址发送 POST 请求来登录,提交用户名和密码。
    • 登录成功后会返回包含 access token 和 refresh token 的响应。
    • 用户可以通过 http://127.0.0.1:8110/one/publish/ 地址发送 GET 请求来获取发布内容列表,但需要在请求头中带上有效的 JWT 进行身份验证。

双 token 验证流程image-20240422213646136

​ 双 token 验证机制,其中 accessToken 过期时间较短,refreshToken 过期时间较长。当 accessToken 过期后,使用 refreshToken 去请求新的 token。

image-20240419092747338

  1. 用户登录向服务端发送账号密码,登录失败返回客户端重新登录。登录成功服务端生成 accessToken 和 refreshToken,返回生成的 token 给客户端。
  2. 在请求拦截器中,请求头中携带 accessToken 请求数据,服务端验证 accessToken 是否过期。token 有效继续请求数据,token 失效返回失效信息到客户端。
  3. 客户端收到服务端发送的请求信息,在二次封装的 axios 的响应拦截器中判断是否有 accessToken 失效的信息,没有返回响应的数据。有失效的信息,就携带 refreshToken 请求新的 accessToken。
  4. 服务端验证 refreshToken 是否有效。有效,重新生成 token, 返回新的 token 和提示信息到客户端,无效,返回无效信息给客户端。
  5. 客户端响应拦截器判断响应信息是否有 refreshToken 有效无效。无效,退出当前登录。有效,重新存储新的 token,继续请求上一次请求的数据。
注意事项
  1. 短token失效,服务端拒绝请求,返回token失效信息,前端请求到新的短token如何再次请求数据,达到无感刷新的效果。
  2. 服务端白名单,成功登录前是还没有请求到token的,那么如果服务端拦截请求,就无法登录。定制白名单,让登录无需进行token验证。

关于双token认证的问题

大佬搭建的接口平台

YApi-高效、易用、功能强大的可视化接口管理平台

# 1 使用auth的user表---》只能传用户名 ,密码校验

# 2 项目中:手机号/用户名/邮箱 + 密码--》也可以登录成功--》simple-jwt就不行了

# 3 自己定制登陆接口--》使用auth的user表
	-签发自己签发
    -认证继续用 simple-jwt的认证即可
    
# 4 编写一个多方式登陆接口
	- 扩写auth的user表---》加入mobile字段
    	-坑:
        	-之前迁移过--》auth的user表已经生成了,就不能扩展写
            -方案一: 创建新项目,从头做
            -方案二:删库,删除迁移记录(咱们自己app和auth和admin)
        	-以后如果要扩写auth的user表,必须在迁移之前就定好,写好
            
    - 编写登陆接口

image-20240420230145760

image-20240420230255944

# 用户模型        # 应用程序.表名
AUTH_USER_MODEL = "one.UserInfo"

Tracking file by folder pattern: migrations
Username: admin
Email address: 363@qq.com
Warning: Password input may be echoed.
Password: xxxxxx
Warning: Password input may be echoed.
Password (again): xxxxxx

  • 38
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在前面的文章中,我们已经介绍了如何使用DRF编写RESTful API和如何进行身份验证。在本文中,我们将继续探讨如何使用DRF实现前后端分离。具体来说,我们将使用Vue.js作为前端框架,并使用axios实现与后端API的通信。 1. 安装Vue.js和axios 首先,我们需要安装Vue.js和axios。我们可以使用npm来进行安装: ``` npm install vue npm install axios ``` 2. 创建Vue.js应用程序 我们可以使用Vue CLI来创建Vue.js应用程序。在命令行中输入以下命令: ``` npm install -g vue-cli vue init webpack myapp ``` 其中,myapp是应用程序的名称。在创建应用程序时,我们需要回答一些问题,例如选择使用哪种模板、是否安装vue-router等。我们可以根据自己的需要进行选择。 3. 编写Vue.js组件 接下来,我们需要编写Vue.js组件来与后端API进行通信。在本例中,我们将创建一个名为“TaskList”的组件,用于显示任务列表并提供添加任务的功能。 在src/components目录下创建TaskList.vue文件,并编写以下代码: ```html <template> <div> <h2>Tasks</h2> <ul> <li v-for="task in tasks" :key="task.id"> {{ task.title }} </li> </ul> <input type="text" v-model="title"> <button @click="addTask">Add Task</button> </div> </template> <script> import axios from 'axios'; export default { data() { return { tasks: [], title: '' }; }, created() { this.getTasks(); }, methods: { getTasks() { axios.get('http://localhost:8000/api/tasks/') .then(response => { this.tasks = response.data; }); }, addTask() { axios.post('http://localhost:8000/api/tasks/', { title: this.title }) .then(response => { this.tasks.push(response.data); this.title = ''; }); } } }; </script> ``` 在这个组件中,我们首先导入axios库,然后定义了一个名为“TaskList”的组件。在data函数中,我们定义了两个变量:tasks用于存储任务列表,title用于存储新任务的标题。在created函数中,我们调用getTasks函数来获取任务列表。在methods对象中,我们定义了两个方法:getTasks用于获取任务列表,addTask用于添加新任务。在getTasks函数中,我们使用axios库进行HTTP GET请求,并在响应中将tasks变量更新为获取的数据。在addTask函数中,我们使用axios库进行HTTP POST请求,并在响应中将新任务添加到tasks变量中。 4. 引入组件 最后,我们需要将TaskList组件引入Vue.js应用程序。在App.vue文件中,我们可以编写以下代码: ```html <template> <div id="app"> <TaskList /> </div> </template> <script> import TaskList from './components/TaskList.vue'; export default { name: 'App', components: { TaskList } }; </script> ``` 在这个文件中,我们首先导入TaskList组件,然后在components对象中注册它。最后,在模板中调用它。 5. 运行应用程序 现在,我们可以使用以下命令启动Vue.js应用程序: ``` npm run dev ``` 在浏览器中访问http://localhost:8080,您将看到一个任务列表和一个添加任务的表单。当您添加新任务时,它将被添加到列表中并保存到后端API中。 总结 在本文中,我们介绍了如何使用Vue.js和axios实现与DRF后端API的通信,并创建了一个名为“TaskList”的组件来显示任务列表和添加新任务。这是一个简单的示例,但您可以使用类似的方法来创建更复杂的应用程序。 ### 回答2: Django前后端分离实践之DRF--09主要是关于Django Rest Framework(DRF)在前后端分离开发中的实践。DRF是基于Django的一款强大的Web API框架,它提供了一系列的功能和工具,使得开发者能够轻松地构建和管理API。 在这个实践中,首先我们需要将前端和后端进行分离。前端可以使用任何JavaScript框架,如Vue.js或React来构建用户界面,并通过HTTP请求与后端进行通信。而后端则是使用Django和DRF来构建API。 DRF提供了一些类和方法,能够帮助我们更方便地开发API。例如,通过使用DRF的序列化器,我们可以轻松地将数据库模型转化为JSON格式。此外,DRF还提供了视图和路由器等组件,使得开发者能够更快速地构建API视图和URL路由。 在实践过程中,我们还可以使用DRF的认证和权限系统来保护API的安全性。DRF支持各种认证方式,如基于Token的认证和基于Session的认证。同时,我们可以基于DRF的权限系统来限制用户对API的访问权限,确保只有经过授权的用户才能进行操作。 此外,DRF还提供了一些其他的功能,如过滤器、分页和搜索等,使得我们能够更精细地控制API的行为和展示方式。 总之,Django前后端分离实践之DRF--09主要介绍了如何使用DRF来构建前后端分离的应用。通过DRF提供的强大功能和工具,我们可以更便捷地开发高效、安全的API,并提供给前端进行交互和展示。 ### 回答3: DRF即Django Rest Framework是一种用于构建Web API的强大工具,它使得前后端分离开发成为可能。在实践中,Django的后端提供数据的存储和处理功能,而前端使用DRF来访问API并展示数据。 首先,我们需要在Django中安装和配置DRF。可以通过在settings.py中添加'django_rest_framework'到INSTALLED_APPS列表中来安装DRF。然后,在urls.py中配置API的路由。 在Django中,我们可以使用数据库模型来定义数据模型,在使用DRF时,我们需要创建一个序列化器类来定义返回给前端的数据结构。序列化器由字段组成,可以定义字段的类型、验证规则等。我们可以使用DRF提供的ModelSerializer来快速创建序列化器类,它会自动根据模型的字段来生成对应的序列化器字段。 在视图中,我们可以使用基于类的视图来处理API请求。DRF提供了一系列的视图类,如APIView、ViewSet等,可以根据实际需求选择使用。视图类中的方法对应不同的HTTP操作,如GET、POST、PUT、DELETE等。 DRF还提供了身份验证、权限控制、过滤、排序等功能,可以根据项目的需求进行配置。 使用DRF的前后端分离实践中,前端可以通过发送GET、POST、PUT等请求来获取和操作数据。后端则负责处理请求并返回响应。前端可以通过AJAX、fetch等方法来发送请求并获取数据,然后使用HTML、CSS和JavaScript来展示数据。 在前后端分离开发中,前端和后端可以并行开发,各自独立测试,并且可以轻松地修改API而不会影响到前端界面。这种开发模式使得团队协作更加高效,同时也方便进行项目的维护和扩展。 总而言之,Django前后端分离实践之DRF可以极大地提升开发效率和团队协作能力。通过合理配置和使用DRF提供的功能,可以实现强大的API开发,使得前后端分离成为一种高效和可行的开发方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值