小程序实现无感登录+权限分配

djngo开发:小程序实现无感登录+权限分配

由来

最近开发一个预约系统,需要区分普通用户和工作人员。由于账号密码/短信验证过于繁琐,因而选择记录openid实现无感登录。(基本小程序都这样操作)

同时事先在数据库中录入客户手机号,即可在用户登录时根据有无手机号来区分普通用户和工作人员。这样在项目交付时,工作人员和普通用户一样可以直接登录无感登录小程序

1. 开发思路

微信的openid是一种唯一标识用户身份的字符串

用户登录小程序,通过手机号快速验证组件获取动态令牌code,后端向微信服务器发送get请求并带上code获取每个用户唯一的openid,然后记录到mysql中,并签发token。该openid就是登录小程序的唯一凭证。

2.简单实现

  • 获取openid,如果通过openid查不用户,就自动新建用户,并返回token。
py 复制代码
#####LoginView###########

code = request.data.get("code")
appid = appid # 微信小程序的appid
appsecret = "xxxxxxxx" # 微信小程序的密钥,登录微信公众平台即可获取
# 获取openid和session_token
querystring = {"appid":appid,"js_code":code,"secret":appsecret,"grant_type":"authorization_code"}
jscode2session = requests.get('https://api.weixin.qq.com/sns/jscode2session',params=querystring)
if not jscode2session.json().get("errcode"):
            data = jscode2session.json()
            ########拿到openid#########
            openid=data.get("openid")
            #######去数据库比对,如果通过openid查到用户并且未被禁用,就新建##########
            try:
                user = models.UserInfo.objects.get(openid)
                if user.is_deleted: # 检查用户是否被禁用
                    return ErrorResponse(msg='用户已被禁用,无法登录',data=data,code=302)
            except models.UserInfo.DoesNotExist: 
               models.UserInfo.objects.create()

3.更进一步:通过手机号来区别普通用户和工作人员

openid虽然做到的唯一性验证,但是当用户数量庞大时,该如何区分用户角色:

  • 一:手动在后台根据已有用户分配权限

  • 二:登录时根据某一标识区分角色

    方法一显然不靠谱,因为用户至少会超过1000人,方法二需要额外标识,显然手机号最合适。

3.1 前端获取手机号的动态令牌

小程序提供了手机号快速验证组件,方便我们获取手机号

bindgetphonenumber 事件回调中的动态令牌code传到开发者后台

html 复制代码
  <view class="title">欢迎来到广盈预约</view>
  <view class="card">
    <view class="button">快捷登录</view>
    <button
      style="opacity: 0"
      class="bottom-button"
      open-type="getPhoneNumber|agreePrivacyAuthorization"
      bindgetphonenumber="getrealtimephonenumber"
      bindagreeprivacyauthorization="handleAgreePrivacyAuthorization"
    >
      同意隐私协议并授权手机号注册
    </button>
  </view>
</view>
js 复制代码
Page({
  getPhoneNumber (e) { console.log(e.detail.code)  // 动态令牌 }
})

注意 :如果你想获取用户手机号就必须添加用户授权《隐私保护协议》bindagreeprivacyauthorization,否则小程序无法上线

3.2 后端带着动态令牌去微信服务器获取手机号

简单来说就是用户登录时数据库中没有手机号对应的用户,后端就会自动建立一个账号,并分配权限为普通用户,然后直接登录。

这样的话,只需要第一次登录时获取手机号,以后登录就可以直接进入系统。

py 复制代码
class RegisterView(APIView):  
    authentication_classes = []
    permission_classes = []
    def getmobile(self,appid,code):
        """获取用户的手机号"""
        try:
            appsecret = "cxxxxxxxxx"
            querystring = {"appid":appid,"secret":appsecret,"grant_type":"client_credential"}
            response = requests.get('https://api.weixin.qq.com/cgi-bin/token',params=querystring)
            access_token = response.json().get("access_token")
            querystring = {"access_token":access_token}
            headers = {"content-type": "application/json"}
            payload = {"code":code}
            mobile =requests.post(f"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={access_token}",json=payload,headers=headers)
            return mobile.json().get('phone_info').get('phoneNumber')
        except Exception as e:
            return None


    def post(self, request):   
        unionid =request.data.get("unionid")
        nickname =request.data.get("nickname")
        openid = request.data.get("openid")
        code = request.data.get("code")
        appid = request.data.get("appid")

        mobile = self.getmobile(appid=appid,code=code)
        if not mobile:
            return ErrorResponse(msg="手机号获取失败")

        defaults = {
            "openid":openid,
            "unionid":unionid,
            "mobile":mobile,
            "nickname":nickname,
        }

        """这条语句将查找一个符合mobile=mobile条件的记录,如果找到就更新 defaults中的字段 ,否则就创建
        注意: 查询的条件必须是唯一的,否则会造成多条数据返回而报错,这个逻辑同 get() 函数。
        注意: 使用的字段,没有唯一的约束,并发的调用这个方法可能会导致多条相同的值插入。
        """
        models.UserInfo.objects.update_or_create(mobile=mobile,defaults=defaults) 
        models.User_GZH.objects.get_or_create(unionid=unionid, defaults={'unionid':unionid})
        return DetailResponse()
相关推荐
计算机学姐6 小时前
基于python+django+vue的旅游网站系统
开发语言·vue.js·python·mysql·django·旅游·web3.py
不染_是非8 小时前
Django学习实战篇六(适合略有基础的新手小白学习)(从0开发项目)
后端·python·学习·django
程序员阿龙8 小时前
[2025]基于微信小程序慢性呼吸系统疾病的健康管理(源码+文档+解答)
微信小程序·自我管理·慢性呼吸系统疾病·健康管理·智能健康管理·肺功能监控
战神刘玉栋12 小时前
《微信小程序实战(2) · 组件封装》
微信小程序·小程序·notepad++
人工智能的苟富贵16 小时前
微信小程序中的实时通讯:TCP/UDP 协议实现详解
tcp/ip·微信小程序·udp
鸠摩智首席音效师16 小时前
如何设置 Django 错误邮件通知 ?
python·django
李宥小哥16 小时前
微信小程序04-常用API上
微信小程序·小程序·notepad++
程序员阿龙16 小时前
计算机毕业设计之:教学平台微信小程序(
微信小程序·小程序·课程设计·在线教育·教育管理系统·个性化教学·学习进度跟踪
Jiaberrr17 小时前
教你如何在微信小程序中轻松实现人脸识别功能
javascript·微信小程序·小程序·人脸识别·百度ai
Hello.Reader17 小时前
ClickHouse 与 Quickwit 集成实现高效查询
python·clickhouse·django·全文检索