Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证

这篇具有很好参考价值的文章主要介绍了Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证

在已经配置好djangorestframework-simplejwt的前提下进行

模型类及序列化器

小程序用户模型类

这里的模型类并未继承django自带的用户模型类,好处是后面小程序用户也是没法进行admin端的,缺点是可能会对django自带的权限管理有影响,如果只有小程序端的用户的话没问题,但是如果还有其它用户的话就可能会出问题,因为在这个模型中是没有密码存在的,只要拿到小程序端生成的用户的code就能够通过登录接口获取到用户的token(小程序端的code每次生成是不同的,有效期应该是5分钟)

class User(models.Model):

    USER_TYPE = ((1, '顾客'),
                 (2, '商家'))

    GENDER = ((0, '男'),
              (1, '女'),
              (2, '未知'))

    username = models.CharField('用户名', max_length=20, blank=True)
    tel = models.BigIntegerField('手机号', unique=True, blank=True, null=True)
    openid = models.CharField('小程序openid', unique=True, max_length=100, blank=True, null=True)
    avatar_url = models.URLField('头像', help_text='头像', null=True, blank=True)
    unionid = models.CharField('小程序unionid', unique=True, max_length=100, blank=True, null=True)
    nickname = models.CharField('微信昵称', max_length=100, blank=True, null=True)
    gender = models.IntegerField('性别', choices=GENDER, default=2)
    type = models.IntegerField('用户类型', choices=USER_TYPE, default=1)
  # 用自定义的用户需要重写此方法
    @property
    def is_authenticated(self):
        """
        Always return True. This is a way to tell if the user has been
        authenticated in templates.
        """
        return True

    def __str__(self):
        return self.openid

    class Meta:
        db_table = 'user'
        verbose_name = '用户管理'
        verbose_name_plural = verbose_name

小程序用户序列化器

小程序用户表中的所有信息,当然可以自己去模型类中加一些,像注册时间或者是更新时间,上次登录时间等,此处只是演示,并未添加


class UserSerializer(serializers.ModelSerializer):
    """用户序列化器"""

    class Meta:
        model = User
        fields = '__all__'

自定义认证类

主要其实是用来获取到用户,其它的方法都是继承了simplejwt的JWTAuthentication中的方法。
在用户app目录下直接去新建一个文件 Authentication.py 写入如下内容

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, AuthenticationFailed

from apps.user.models import User

# 自定义的解析token的方法 下面会用到
from utils.token_get_user import get_user

class MyJWTAuthentication(JWTAuthentication):
    """
    继承JWTAuthentication类, 返回自定义User对象
    """
	# get_user用于返回用户,重写后在其它地方使用request.user时可以直接得到自定义的小程序用户
    def get_user(self, validated_token):
        try:
            user_id = get_user_id(str(validated_token))  # 此处为自定义的解析token方法, 可以解码token得到其中的信息,重点是拿到user_id 用于后续的获取用户
        except KeyError:
            raise InvalidToken(_('Token不包含可识别的用户标识'))

        try:
            user = User.objects.get(**{'id': user_id})
        except User.DoesNotExist:
            raise AuthenticationFailed(_('未找到用户'), code='user_not_found')

        return user


get_user_id方法: 用于解析我们的token得到user_id

import jwt
import time

# ConvLife为我的项目名称,此处导入的是项目的settings,主要是拿到自定义的secret_key
from ConvLife import settings


def get_user_id(t):
    """根据token得到当前用户user_id"""
    try:
        decode_data = jwt.decode(t, secret_key=settings.SECRET_KEY, verify=False, algorithms=['HS256'])
        print(decode_data)
        if int(decode_data['exp']) < int(time.time()):
            return "token过期"
        return decode_data['user_id']
    except Exception as e:
        return "token错误:\n"+str(e)

小程序登录及手动签发token

用户视图

在登录这其实就是重写了create,思路大概:通过用户传入的code获取到openid(获取不到openid的情况就是code出错或者用户未输传入code),然后使用openid去用户表查找用户,如果不存在则新建,存在则读取到,然后针对读取或者新建的用户生成一个token,再返回给前端

# get_wx_openid 是调用微信开放接口,使用小程序传到后端的code去请求openid,openid作为唯一标识
from utils.wx import get_wx_openid

from utils.Authentication import MyJWTAuthentication


class WxLogin(mixins.CreateModelMixin, viewsets.GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def create(self, request, *args, **kwargs):
		# code是小程序端可以直接获取到的,获取到后和userinfo一起Post到后端 
        code = request.data.get('code', '')
        
        # 通过传入的code来获取openid
        openid_res = get_wx_openid(code)
        try:
            openid = openid_res['openid'] or ''
        except KeyError as e:
            return Response({'message': '微信调用失败'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 尝试查找用户,如果用户存在则读取用户,用户不存在则新建用户
        try:
            user = User.objects.get(openid=openid)
        except User.DoesNotExist:
        	# userinfo 是小程序端可以直接获取到的,获取到后和code 一起Post到后端 
            user_info = request.data.get('userInfo')
            print(user_info)
            user = User.objects.create(openid=openid,
                                       avatar_url=user_info['avatarUrl'],
                                       nickname=str(user_info['nickName']),
                                       gender=user_info['gender'])
            user.save()

        # 手动签发jwt token
        refresh = RefreshToken.for_user(user)
        resp_data = {
            'user_id': user.id,
            "refresh": str(refresh),
            "access": str(refresh.access_token)
        }
        return Response(resp_data)

路由

这里直接配置成前端发送code和userinfo来请求的了,需要测试的话请求得先去在微信小程序端获取到code,要带着code去请求,不然会报错!

from .views import WxLogin

router = routers.SimpleRouter()

# 小程序用户
router.register(r'login/', WxLogin, basename="login")

urlpatterns = router.urls

使用错误code获取token,失败
Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证

使用正确code获取token,成功
Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证

使用

在需要小程序用户登录验证的视图中加入permission_classes = [permissions.IsAuthenticated]authentication_classes = (MyJWTAuthentication,),当获取用户收藏或者收藏时就会需要用户是登录用户并会使用我们自定义的类,在登录的视图类中不要加哦,只是在需要验证的视图类中加上。

例如:

from rest_framework import mixins
from rest_framework.permissions import IsAuthenticated

from .models import UserFav
from .serializers import UserFavSerializer

from utils.Authentication import MyJWTAuthentication


class UserFavViewSet(mixins.CreateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    create: 用户收藏藏品
    取消收藏商品

    list: 获取收藏藏品列表
    """
    queryset = UserFav.objects.all()
    serializer_class = UserFavSerializer
	
	permission_classes = [IsAuthenticated]  # 增加此行
    authentication_classes = [MyJWTAuthentication, ]   # 增加此行

    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ('goods__good_name', 'goods__goods_brief')
    
    # 获取到当前用户的收藏列表
    def get_queryset(self):
        return UserFav.objects.filter(user=self.request.user.id)


新手写博客,主要想记录下自己学习中遇到的问题及解决的过程,很多不足的地方,如有讲得不明白的地方看官请见谅,也可以私信我,看到后会尽快回复的文章来源地址https://www.toymoban.com/news/detail-499247.html

到了这里,关于Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django DRF - 【Token】认证基本使用

    Django Rest Framework Token 是Django Rest Framework中的一个扩展,用于实现用户认证和授权。它为每个用户生成一个唯一的Token,并将其存储在数据库中。在用户进行API请求时,用户需要在请求的HTTP Header中包含Token,这样服务器就可以验证用户的身份。 迁移完成会生成 authtoken_token 这张

    2024年02月12日
    浏览(34)
  • DRF JWT认证进阶

    (1)模型准备 模型准备(继承 django 的 auth_user 表) 添加配置文件,修改用户模型表为自定义表 (2)知识点绑定方法 详情请见:Python 面向对象之绑定和非绑定方法_python 绑定方法-CSDN博客 实例方法 当 对象调用 实例方法时( 对象.实例方法() ), 自动将对象当作第一个参数传

    2024年04月27日
    浏览(23)
  • drf——jwt

    2024年02月06日
    浏览(39)
  • Django 框架添加管理员,完成对普通用户信息管理

    前情回顾:Django框架 完成用户登录注册 一般管理员都是直接指定,不开放页面注册,可以直接手动在数据库添加,Django框架提供了方法,让我们直接创建管理员,步骤如下: 打开pycharm下面的命令行终端 输入命令 按照提示进行输入信息 打开数据库,可以看出,已经帮我们插

    2024年01月16日
    浏览(43)
  • 【django开发手册】详解drf filter中DjangoFilterBackend,SearchFilter,OrderingFilter使用方式

    💖 作者简介:大家好,我是Zeeland,开源建设者与全栈领域优质创作者。 📝 CSDN主页:Zeeland🔥 📣 我的博客:Zeeland 📚 Github主页: Undertone0809 (Zeeland) 🎉 支持我:点赞👍+收藏⭐️+留言📝 💬介绍:The mixture of software dev+Iot+ml+anything🔥 【django开发手册】Django 中使用自定义用

    2024年02月09日
    浏览(52)
  • Django自定义用户错误记录

    执行: 1 setttings.py: 先注释掉 django.contrib.admin 2 注释掉urls.py path(“admin/”, admin.site.urls), 执行3: $ python3 manage.py migrate 再取消注释:1,2 再次执行4 $ python3 manage.py migrate1

    2024年02月16日
    浏览(35)
  • django 人机校验我是人类-使用hCaptcha或Turnstile代替simple-captcha

    此教程非权威,仅是个人搭建网站中探索的总结,留给后人的基本流程的简介 首先,确保你已经完成了django知识的学习, 以便不出现未经了解且不易理解的错误,本文不会叙述基础教程,如若此, 请跳转至djangoproject官网教程. 好了! 让我们开始探索的旅途! CAPTCHA项目是Co

    2024年02月12日
    浏览(46)
  • Django之JWT库与SimpleJWT库的使用

    JWT(JSON Web Token)是一种轻量级的认证和授权机制,它是基于 JSON 格式的标准,用于在网络应用程序或服务之间传递声明。 JWT官网: https://jwt.io/ 特点: 主要应用: JWT通常用于身份验证和授权。当用户成功登录时,服务器会生成一个 JWT,并将其返回给客户端。客户端随后将

    2024年02月14日
    浏览(31)
  • Django用户登录验证和自定义验证类

    用户登录时,使用 authenticate 验证用户名和密码是否正确,正确则返回一个用户对象。 用户名默认的字段名是 username 密码默认的字段名是 password 将已验证的用户添加到当前会话(session)中,可使用 login() 函数完成。 注意,如果用户未登录,logout() 不会报错。 调用 logout() 后,

    2024年02月14日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包