Django jwt 自定义用户表实现

本文介绍了如何在Django中使用rest_framework_simplejwt库实现JWT(JSON Web Tokens)认证,并针对自定义用户模型进行改造。配置了全局权限控制,设置了token的有效时长,并展示了自定义登录视图、认证类以及权限类的实现,以适应自定义User模型的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

由于jwt默认使用django自带的User表,若使用自定义User表需要改造获取token的视图,继承官方文档提供的视图 TokenObtainPairSerializer,TokenObtainPairView

自带用户表的实现参考:  基于Django的JWT 实现(rest_framework_simplejwt 库)_叱咤少帅(少帅)的博客-CSDN博客

settings.py 配置

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

## 全局配置
REST_FRAMEWORK = {
   # 设置所有接口都需要被验证
  'DEFAULT_PERMISSION_CLASSES': (
      # 设置所有接口都需要被验证
       'rest_framework.permissions.IsAuthenticated',  # 默认权限为验证用户
  ),
}

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

devops/urls.py 配置

from django.contrib import admin
from django.urls import path,include


urlpatterns = [
    path('admin/', admin.site.urls),
    # 用户模块
    path("users/",include('users.urls')),
    # 商场模块路径
    path("mall/",include('mall.urls')),
]

users/urls.py配置

from django.urls import path
from users.auth import MyTokenObtainPairView
from users.views import ListView

# jwt内部实现的登陆视图
from rest_framework_simplejwt.views import (TokenObtainPairView, TokenRefreshView)

urlpatterns =[
    path(r'lg', TokenObtainPairView.as_view(), name="obtain_token"),
    path(r'login', MyTokenObtainPairView.as_view(),name="login"),  # 自定义用户表返回token
    path(r'list',ListView.as_view(),name="list"),
]

users/auth.py配置

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, AuthenticationFailed
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework import exceptions
import time

from django.utils.translation import gettext_lazy as _

from users.models import User


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    """
    自定义登录认证,使用自有用户表
    """
    username_field = 'username'
    def validate(self, attrs):
        authenticate_kwargs = {self.username_field: attrs[self.username_field], 'password': attrs['password']}
        print(authenticate_kwargs)
        try:
            user = User.objects.get(**authenticate_kwargs)
        except Exception as e:
            raise exceptions.NotFound(e.args[0])

        refresh = self.get_token(user)
        # token的 过期时间
        timestamp = refresh.access_token.payload['exp']  # 有效期-时间戳
        time_local = time.localtime(int(timestamp))
        expire_time = time.strftime("%Y-%m-%d %H:%M:%S", time_local)

        data = {"userId": user.id,"username":user.username,"token": str(refresh.access_token), "refresh": str(refresh),"expire":expire_time}
        return data


class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer


class MyJWTAuthentication(JWTAuthentication):
    '''
    修改JWT认证类,返回自定义User表对象
    '''
    def get_user(self, validated_token):
        try:
            user_id = validated_token['user_id']
        except KeyError:
            raise InvalidToken(_('Token contained no recognizable user identification'))

        try:
            user = User.objects.get(**{
    'id': user_id})
        except User.DoesNotExist:
            raise AuthenticationFailed(_('User not found'), code='user_not_found')

        return user

users/views.py 配置

from django.http import  HttpResponse,JsonResponse
from rest_framework.views import Response
from rest_framework.views import APIView
from rest_framework import permissions
from rest_framework_simplejwt import authentication

# Create your views here.

##  不需要携带token就能访问接口
def ListShops(requests):
    return HttpResponse("this is shop list")

# 需要携带token才可以访问的视图
class ListView(APIView):
    #  需要token才可以访问的视图
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = (authentication.JWTAuthentication,)

    def get(self, request, *args, **kwargs):
        return Response('Get OK')

    def post(self, request, *args, **kwargs):
        return Response('Post OK')

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叱咤少帅(少帅)

如果文章对你有帮助就打赏下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值