前言

在开发小程序的过程中, 用户的认证是必不可少的,而微信又取消了小程序的自己认证,所以,我们只能通过微信进行授权登录,而如果将微信授权的信息录入到自己的表中,则需要做一点点的开发,官方文档

微信小程序的后端开发和普通的restful API 大致上相同,只不过要注意以下几点限制

  • 必须使用HTTPS协议请求后端服务器
  • 不支持COOKIE
  • 不支持django内置的user登录, 因为它使用的是微信的用户系统

原理图

只获取openid,只调用wx.login获取code交给后台即可,如果还要获取用户详细信息还要接着调用wx.getUserInfo获取encryptedDataiv提交后台解密用户信息

@api_view(['GET','POST'])
def wx_login(request):
    openidUrl = 'https://api.weixin.qq.com/sns/jscode2session?'
    code = request.GET['code']
    res = requests.get(
        url = openidUrl,
        params = {
            'appid':APPID,
            'secret':APP_SECRET,
            'js_code':code,
            'grant_type':'authorization_code'
        }
    ).json()
    openid = res['openid']
    return Response(openid

这样,我们便获取到了openid,然后返回给前端即可

如果要换取用户信息,则需要前端再次请求我们服务器,需要传入encryptedData ivsession_key来获取用户的信息,

encryptedData就是获取到的用户信息,只是得解密一下,通过iv

#  解密类
class WXBizDataCrypt:
    def __init__(self, appId, sessionKey):
        self.appId = appId
        self.sessionKey = sessionKey

    def decrypt(self, encryptedData, iv):
        # base64 decode
        sessionKey = base64.b64decode(self.sessionKey)
        encryptedData = base64.b64decode(encryptedData)
        iv = base64.b64decode(iv)

        cipher = AES.new(sessionKey, AES.MODE_CBC, iv)

        decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData)))
        if decrypted['watermark']['appid'] != self.appId:
            raise Exception('Invalid Buffer')

        return decrypted

    def _unpad(self, s):
        return s[:-ord(s[len(s)-1:])]
def main():
    appId = '你的appid'
    sessionKey = '获取到的sessionkey'
    encryptedData = '获取openid那里的数据'
    iv = '获取openid那里的数据'

    pc = WXBizDataCrypt(appId, sessionKey)

    res = pc.decrypt(encryptedData, iv)
    print(res)

res就是解密出来的内容,就是用户的信息

至此,前台将openid存下,而后台,获取了用户信息,该入库还是该做怎样的操作,就可以自定义了,我是将其入库了,完整代码如下:

class Applets_RegisterView(APIView):

    def post(self,request):
        session_key = request.data.get('session_key')
        encryptedData = request.data.get("encryptedData")
        iv = request.data.get("iv")
        pc = WXBizDataCrypt(APPID, session_key)
        data = pc.decrypt(encryptedData, iv)
        username = data['nickName']
        avatar = data['avatarUrl']
        gender = data['gender']
        user_data = {
            'username':username,
            'avatar':avatar,
            'gender':gender,
        }
        with transaction.atomic():
            try:
                userobj = RegisterSerializer(data=user_data)
                if userobj.is_valid() and secretobj.is_valid():
                    userobj.save()
                    return Response({'code': 1000, 'msg': '注册成功'})
                else:
                    return Response({'code':1004,'msg':'网络错误,请稍后再试'})
            except Exception as exc:
                print(exc)
                return Response({'code': 1004, 'msg': '网络错误,请稍后再试'})

被一个小小的登录绊倒,我也是没想到的,感谢有位大神孜孜不倦的一直给我讲解。