目录

  • Django使用DRF + Simple JWT 完成小程序使用自定义用户的注册、登录和认证
    • 模型类及序列化器
      • 小程序用户模型类
      • 小程序用户序列化器
      • 自定义认证类
    • 小程序登录及手动签发token
      • 用户视图
    • 路由
    • 使用

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)# 用自定义的用户需要重写此方法@propertydef is_authenticated(self):"""Always return True. This is a way to tell if the user has beenauthenticated in templates."""return Truedef __str__(self):return self.openidclass Meta:db_table = 'user'verbose_name = '用户管理'verbose_name_plural = verbose_name

小程序用户序列化器

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


class UserSerializer(serializers.ModelSerializer):"""用户序列化器"""class Meta:model = Userfields = '__all__'

自定义认证类

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

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, AuthenticationFailedfrom apps.user.models import User# 自定义的解析token的方法 下面会用到
from utils.token_get_user import get_userclass 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 settingsdef 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_openidfrom utils.Authentication import MyJWTAuthenticationclass WxLogin(mixins.CreateModelMixin, viewsets.GenericViewSet):queryset = User.objects.all()serializer_class = UserSerializerdef create(self, request, *args, **kwargs):# code是小程序端可以直接获取到的,获取到后和userinfo一起Post到后端 code = request.data.get('code', '')# 通过传入的code来获取openidopenid_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 tokenrefresh = 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 WxLoginrouter = routers.SimpleRouter()# 小程序用户
router.register(r'login/', WxLogin, basename="login")urlpatterns = router.urls

使用错误code获取token,失败

使用正确code获取token,成功

使用

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

例如:

from rest_framework import mixins
from rest_framework.permissions import IsAuthenticatedfrom .models import UserFav
from .serializers import UserFavSerializerfrom utils.Authentication import MyJWTAuthenticationclass UserFavViewSet(mixins.CreateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):"""create: 用户收藏藏品取消收藏商品list: 获取收藏藏品列表"""queryset = UserFav.objects.all()serializer_class = UserFavSerializerpermission_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)

新手写博客,主要想记录下自己学习中遇到的问题及解决的过程,很多不足的地方,如有讲得不明白的地方看官请见谅,也可以私信我,看到后会尽快回复的

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

  1. Spring Boot + Spring Security + JWT + 微信小程序登录

    Spring Boot + Spring Security + JWT + 微信小程序登录整合教程 参考文章 文章目录 整合思想 整合步骤 1. AuthenticationToken 2. Auth ...

  2. 微信小程序云开发用户身份登录_微信小程序开发用户授权登录(下)

    如果开发者拥有多个移动应用.网站应用.和公众帐号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用.网站应用和公众帐号(包括小程序),用户的 Un ...

  3. 微信小程序图标不支持html,微信小程序实现自定义加载图标功能

    效果图 实现思路 1.首先通过HTML+CSS实现加载动画的静态效果: 2.根据需求给每个动画设计不同的动画效果. 例如第一个加载图标的静态绘制 1.首先确定动画的盒子宽高: 2.设置盒子中每一个长方 ...

  4. 微信小程序云开发用户身份登录_云开发版的微信商城小程序第一章

    我们经过前面小程序基础和云开发基础的学习,今天就来带大家实现一个综合项目,上线一款属于自己的微信商城小程序. 文末有彩蛋 如果你有小程序基础可以跳过上面的基础,直接看下面的,如果没有小程序基础,建议你 ...

  5. 微信小程序开发——小程序API获取用户位置及异常流处理完整示例

    前言: 小程序需要添加一个定位功能,主要的就是获取用户位置的经纬度,然后根据用户经纬度进行一些判断操作. 在小程序提供的Api中,获取用户定位信息的主要Api是 wx.getLocation(obj) ...

  6. 微信小程序python解析获取用户手机号_python获取微信小程序openid及用户信息

    填坑记录:1.个人微信公众订阅号是不能申请微信认证的.公众号的类型在注册时一旦选择就不能更改,微信公众号认证的功能除个人订阅号外,都可以申请认证,因而个人订阅号不能申请认证.这句话的意思就是个人订阅号 ...

  7. 微信小程序可以加服务器上的字体,微信小程序中自定义字体

    微信小程序支持自定义字体开放出来也有段时间,这边整理下使用自定义字体中,容易忽略的一些问题,和简便的全局自定义方式.如果是同时加载两种字体包,先下载下来的会被后下载下来的字体包给覆盖. 官网接口文档 ...

  8. 微信小程序之自定义模态弹窗(带动画)实例

    代码地址如下: http://www.demodashi.com/demo/13991.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.c ...

  9. 微信小程序之——自定义分享按钮(完整版)

    声明 onShareAppMessage 函数 onShareAppMessage() { return {          title: '弹出分享时显示的分享标题'        desc: ' ...

  10. 小程序获取用户信息 php发送数据库,qq小程序如何获取用户信息并存入数据库实例...

    今天给大家带来qq小程序如何获取用户信息并存入数据库的实例,希望能够帮助到大家,让大家不仅知道如何下载qq小程序源码,还能懂得去何用,如何去改,甚至是如何去创造,如果你有好的qq小程序源码出售,可以联 ...

最新文章

  1. 元数据驱动的微服务架构(上)
  2. 堆、栈、自由存储区、全局/静态存储区、常量存储区比较
  3. 更简单的调试Release版本Optimize code的.NET程序集
  4. 理解ArcIMS投影元素
  5. python黑色的_python – 将RGB转换为黑色或白色
  6. java mysql 行锁_Java如何实现对Mysql数据库的行锁?
  7. 漫画:如何用Zookeeper实现分布式锁?
  8. IT人的好习惯和不良习惯总结
  9. Toolbar设置详解----掉坑总结
  10. ant指定servlet版本_[转载]程序开发常见错误
  11. BZOJ1823[JSOI2010]满汉全席——2-SAT+tarjan缩点
  12. python常问问题_Python新手在作用域方面经常容易碰到的问题
  13. 图形化服务端svn(win 10)
  14. scrapy[skp]快速入门
  15. uniapp滑动图片验证
  16. chm打开秒退_无法打开chm文件
  17. python浪漫代码表白npy_【交大表白墙】表白dxy小姐姐,十里春风不如你,三里桃花不及卿,要每天开心哦!...
  18. 趣谈充电IC的电源路径管理功能
  19. php+bmp+加密,郁闷啊,谁知道BMP图片加密技术吗
  20. [JZOJ3337] 【NOI2013模拟】wyl8899的TLE

热门文章

  1. 微信公众号服务器需要备案,微擎不备案可以用吗?微信公众号开发域名一定要备案吗?...
  2. Spring Cloud CAP 简述
  3. 高并发设计的技术方案
  4. C#实战010:Excel操作-查询Excel中的数据
  5. 杭州小伙逆行-没有生活,只有活着
  6. CSDN文章如何设置【分级标题】和【目录】
  7. Latex/CTex/WinEdt自动编号小标题序号(条目/编号/描述)
  8. 网络性能测试(系统层面、针对Linux、安卓)
  9. 非专业学生如何系统的学习计算机编程?
  10. C++学习之路——名字空间与模板