Code de numérisation du compte officiel WeChat pour obtenir la connexion au site Web - Version Django + Vue - Tutoriel de niveau nounou super détaillé


Il existe trois façons de réaliser la connexion par code de balayage WeChat sur la page Web :

  • PlanA : plate-forme ouverte Wechat - certification requise - 300 yuans
  • PlanB : Compte public Wechat - nécessite un compte de service et a été certifié - 300 yuans
  • PlanC : Mini programmes Wechat - Mini programmes qui ont été enregistrés en ligne - 0 yuan

Ce tutoriel est un exemple de connexion avec le code de scan du compte officiel WeChat de Django+vue. De la connexion avec le code de scan WeChat, de l'enregistrement du compte officiel à la réalisation finale de l'ensemble du processus, un lien github sera joint, qui n'est qu'un idée de base, puis apportez des modifications en fonction de votre propre situation. Suivez le processus étape par étape, il se réalisera certainement. Les détails seront listés.

démo pour obtenir l'effet final

insérez la description de l'image ici
insérez la description de l'image ici



Cet article implémente la logique et le processus : utilisez le code QR temporaire fourni par WeChat pour revenir au front-end et activez les longues interrogations sur le front-end pour demander le statut de connexion du back-end. L'utilisateur scanne le code pour accéder au compte officiel WeChat. S'il s'agit d'un nouvel utilisateur, il doit faire attention. Après avoir suivi, WeChat reviendra au compte officiel. 新用户登录成功S'il s'agit d'un ancien utilisateur, WeChat reviendra au compte officiel. compte 老用户登录成功. Après être revenu sur le compte officiel, enregistrez les informations d'identification de la clé pour l'utilisateur correspondant. La longue requête d'interrogation frontale trouve que la base de données contient ces données, puis renvoie les informations sur l'utilisateur et la connexion est réussie. Une fois la longue interrogation terminée, le frontal saute pour indiquer que la connexion est réussie.


Demander un numéro de test


  • Créer un compte public

La première consiste à enregistrer un compte officiel WeChat, enregistrez-vous simplement, mais si vous souhaitez l'utiliser en ligne, n'oubliez pas de demander un compte de service.En ce qui concerne la différence entre le compte de service et le compte d'abonnement, je n'entrerai pas dans les détails. Si vous avez des besoins pertinents, vous pouvez accéder à la vue officielle de WeChat.

Une fois l'inscription terminée, cliquez sur 设置与开发le bas du côté gauche 接口权限pour voir simplement les catégories de comptes officiels requis pour ces fonctions connexes. Généralement, ce que nous demandons est un numéro individuel, qui n'a fondamentalement aucune fonction, nous ne pouvons donc publier que des articles.
insérez la description de l'image ici

Lien d'enregistrement du compte public
https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN



  • Entrer le numéro de test

开发者工具Emplacement : sous la barre de navigation de gauche公众平台测试账号

insérez la description de l'image ici

Après avoir entré, vous recevrez un appID et un appsecret , qui sont des paramètres clés et seront utilisés pour des tests ultérieurs. Ces informations de configuration d'interface sont la clé pour interagir avec le backend WeChat.

insérez la description de l'image ici



  • Implémenter les informations de configuration de l'interface

insérez la description de l'image ici

Pour interagir avec WeChat, vous devez configurer les informations via cette interface. Après avoir terminé, cliquez sur Soumettre pour le test, et vous pouvez passer aux opérations suivantes après avoir réussi le
test. Remarque :

URL必须 http:// 或者 https:// 开头,分别支持80端口和443端口
Token为英文或数字,长度为3-32字符

PS:意思就是你要有一个在线上的服务器,开启了80端口和443端口
然后你填写一个接口的URL,确保线上服务器的这个接口能用,能被微信访问到
然后在你填写的后端API上,做出对微信的响应

Lien d'origine des informations de configuration de l'interface : https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html


Idées d'implémentation de Django :

from django.http import HttpResponse
from rest_framework.response import Response
from rest_framework.views import APIView
import hashlib

class WeChatSignature(APIView):
    def get(self, request):
        signature = request.query_params.get("signature")
        timestamp = request.query_params.get("timestamp")
        nonce = request.query_params.get("nonce")
        yue_token = 'yueyue'
        sort_str = ''.join(sorted([yue_token, timestamp, nonce]))
        hash_str = hashlib.sha1(sort_str.encode()).hexdigest()
        if hash_str == signature:
            return HttpResponse(request.query_params.get("echostr"), content_type="text/html; charset=utf-8")
        else:
            return Response("Invalid signature", status=403)

Après avoir rempli l'URL et le jeton, cliquez sur Soumettre.Le jeton rempli dans le compte officiel WeChat doit être le même que le yue_token dans mon exemple de code. Copiez simplement les autres. Si WeChat est accessible et vérifié avec succès avec Token





Obtenir le code QR avec paramètres


Ce qui précède est le travail d'amarrage préliminaire, puis le code d'application sera décrit. Tout d'abord, le frontal doit ouvrir la page pour demander le code QR pour la connexion, et le back-end visite WeChat pour obtenir le lien du code QR en fonction de la demande. Il est recommandé de lire la documentation. Certains paramètres et détails doivent être pris en compte. Si vous utilisez Django, vous pouvez comprendre le sens général en regardant directement mon code.

Génération de code QR avec paramètres Lien d'origine : https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html

Étapes de mise en œuvre :

  • Obtenir l'identifiant d'appel de l'interface globale du compte officiel (durée de validité 2h) AccessToken
  • Obtenir le QR code Ticket
  • URL d'épissage du ticket pour obtenir l'URL du code QR
  • Renvoie la scène (utilisée dans le dernier sondage) et l'url au front-end

Code Django :

import requests
import uuid
import json

# Demo先定义在View中,这两个参数在测试号管理页看得到
appID = "wx8axxxxxx236efe2a"
appSecret = "131b8d9dxxxxxxxx11d3b751ce6b2"

class WeChatLogin(APIView):
    """
    微信登录
    """

    def get(self, request):
        qr_data = self.createShortTicket(str(uuid.uuid4()))
        qr_code_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={}".format(qr_data[0])
        return Response({
    
    'url': qr_code_url, 'scene': qr_data[1]})

    def createShortTicket(self, scene_str):
        """
        生成短效二维码
        :param scene_str:
        :return:
        """
        print("scene_str-------{}".format(scene_str))
        url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={}".format(self.getAccessToken())
        data = {
    
    
            "expire_seconds": 180,              # 二维码有效时间, 以秒为单位
            "action_name": "QR_STR_SCENE",      # 二维码类型, QR_STR_SCENE为临时的字符串参数值
            "action_info": {
    
                        # 二维码详细信息
                "scene": {
    
    
                    "scene_str": scene_str      # 场景值ID(字符串形式的ID, 字符串类型, 长度限制为1到64
                }
            }
        }
        return [json.loads(requests.post(url, json=data).content.decode("utf-8")).get("ticket"), scene_str]

    def getAccessToken(self):
        """
        获取公众号全局接口调用凭证(有效期2h)
        建议公众号开发者使用中控服务器统一获取和刷新access_token
        """
        url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}' \
            .format(appID, appSecret)
        return requests.get(url).json().get('access_token')

Code de vue :

getQrUrl() {
    
    
      axios.get('https://api.xxxxx.pro/api/weChatLogin').then((res) => {
    
    
        console.log(res.data);
        this.qr_url = res.data.url
        this.scene = res.data.scene
        this.loading = false
      })
    }
// getQrUrl我放mounted里面的,打开页面就会执行这个方法

À ce moment, l'URL obtenue par le frontal est l'URL du code QR. Vous pouvez directement cliquer pour afficher le code QR, et vous pouvez l'intégrer vous-même dans l'img.



Gérer le rappel du code de numérisation de l'utilisateur

Ce code QR contiendra le ticket et la scène, ainsi que le paramètre que vous souhaitez utiliser comme seul identifiant pour vérifier que la connexion a réussi. J'utilise la scène ici. Il sera beaucoup plus pratique d'utiliser le ticket, et le code est trop paresseux pour être changé. Il n'était pas sûr que le ticket entre en conflit avec la décision de concurrence avant. Il y a beaucoup d'impressions écrites ici pour les tests, supprimez-les simplement en fonction de vos besoins.
Il doit être clair ici que la méthode get de l'interface WeChatSignature que vous avez définie est utilisée pour la vérification de WeChat, et la publication est ce que WeChat appellera pour vous.
Une fois que l'utilisateur a scanné le code QR que vous avez donné pour se connecter. WeChat rappellera un XML sur votre serveur. Utilisez simplement ET pour l'analyser, puis obtenez les paramètres dont vous avez besoin. J'ai écrit beaucoup de jugements ici. Vous pouvez lire le document original pour comprendre le type d'événement.

Suivre/ne plus suivre le document original de l'événement :
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
Document officiel du message de réponse du compte officiel :
https://developers.weixin.qq.com/doc/offiaccount /Message_Management/Passive_user_reply_message.html#0

Vous pouvez d'abord imprimer le xml pour voir
insérez la description de l'image ici

Code Django :


import xml.etree.ElementTree as ET
from django.utils import timezone
from app.models import TextMsg, User

class WeChatSignature(APIView):
    def get(self, request):
        signature = request.query_params.get("signature")
        timestamp = request.query_params.get("timestamp")
        nonce = request.query_params.get("nonce")
        yue_token = 'yueyue'
        sort_str = ''.join(sorted([yue_token, timestamp, nonce]))
        hash_str = hashlib.sha1(sort_str.encode()).hexdigest()
        if hash_str == signature:
            return HttpResponse(request.query_params.get("echostr"), content_type="text/html; charset=utf-8")
        else:
            return Response("Invalid signature", status=403)

    def post(self, request):
        """
        to_user_name: 公众号的微信号
        from_user_name: 发送方OpenId
        create_time:消息创建时间(时间戳)
        msg_type: 消息类型
        :return:
        """
        wx_data = request.body
        xml_data = ET.fromstring(wx_data)
        to_user_name = xml_data.find('ToUserName').text
        from_user_name = xml_data.find('FromUserName').text
        create_time = xml_data.find('CreateTime').text
        msg_type = xml_data.find('MsgType').text
        event_key = xml_data.find('EventKey').text
        print('---------------------------')
        print("EventKey---------{}".format(event_key))
        print('---------------------------')
        if msg_type == 'event':
            event = xml_data.find('Event').text
            print(event)
            # 如果未关注
            if event == 'subscribe':
                tmp_scene_str = event_key.split('_')[1]
                scene_str = User.objects.filter(tmp_scene_str=tmp_scene_str)
                # 如果查询到此凭证已经存在,就证明此二维码已经被人扫过且登录了。直接走else
                if not scene_str.exists():
                    ticket = xml_data.find('Ticket').text
                    print("ticket-----------{}".format(ticket))
                    datetime_obj = timezone.datetime.fromtimestamp(int(create_time))
                    create_time = datetime_obj.strftime('%Y-%m-%d %H:%M:%S')
                    new_user = User.objects.get_or_create(openId=from_user_name)[0]
                    new_user.tmp_scene_str = tmp_scene_str
                    new_user.lastLoginTime = create_time
                    new_user.save()
                    xml_text = TextMsg(to_user_name, from_user_name, '新用户--登录成功').structReply()
                else:
                    xml_text = TextMsg(to_user_name, from_user_name, '二维码已失效').structReply()
                return HttpResponse(xml_text)
            # 如果关注了
            elif event == 'SCAN':
                scene_str = User.objects.filter(tmp_scene_str=event_key)
                # 同上,码被扫过,登录了就不走这里了
                if not scene_str.exists():
                    ticket = xml_data.find('Ticket').text
                    print("ticket-----------{}".format(ticket))
                    datetime_obj = timezone.datetime.fromtimestamp(int(create_time))
                    create_time = datetime_obj.strftime('%Y-%m-%d %H:%M:%S')
                    User.objects.filter(openId=from_user_name).update(tmp_scene_str=event_key, lastLoginTime=create_time)
                    xml_text = TextMsg(to_user_name, from_user_name, '老用户--登录成功').structReply()
                else:
                    xml_text = TextMsg(to_user_name, from_user_name, '二维码已失效').structReply()
                return HttpResponse(xml_text)
         # 如果不是你已知的微信回调,就返回一个故障。。
        xml_text = TextMsg(to_user_name, from_user_name, '服务器故障,请联系管理员或重试').structReply()
        return HttpResponse(xml_text)

Expliquez la fonction du code ci-dessus, qui est de juger le rappel de WeChat, s'il s'agit d'un événement qui a été suivi ou non. Allez dans la table User pour savoir s'il existe cet event_key. L'event_key que WeChat vous rappelle est la scene_str que vous avez définie auparavant. Mais notez qu'il y a une différence entre faire attention et revenir pour non suivi.L'un a un préfixe et l'autre non.Le document est écrit, allez y jeter un œil, et il est également géré dans mon code. Sachez quel utilisateur est connecté via from_user_name, puis enregistrez scene_str en tant qu'informations d'identification temporaires. Le xml renvoyé à WeChat doit être traité et analysé, ici je le définis dans models.py. Il s'agit de la méthode TextMsg, et l'utilisateur est également collé en passant. La HttpResponse qui est formatée et renvoyée à la chaîne est renvoyée au compte officiel WeChat. Suivez la peinture de la calebasse et changez-la vous-même. Lors de l'interrogation frontale ultérieure, il vous suffit de savoir si scene_str existe dans la base de données. S'il existe, renvoyez les données utilisateur correspondant à cette scene_str au frontal.

modèles.py

from django.db import models
import time

class TextMsg:
    def __init__(self, to_user, from_user, recv_msg):
        self._toUser = to_user
        self._fromUser = from_user
        self._recvMsg = recv_msg
        self._nowTime = int(time.time())

    def structReply(self):
        text = """
                <xml>
                <ToUserName><![CDATA[{}]]></ToUserName>
                <FromUserName><![CDATA[{}]]></FromUserName>
                <CreateTime>{}</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[{}]]></Content>
                </xml>
                """.format(self._fromUser, self._toUser, self._nowTime, self._recvMsg)  # 前面两个参数的顺序需要特别注意
        return text


class User(models.Model):
    openId = models.CharField(null=True, blank=True, max_length=200, verbose_name='用户唯一凭证')
    tmp_scene_str = models.CharField(null=True, blank=True, max_length=100, verbose_name='登录临时凭证')
    lastLoginTime = models.CharField(null=True, blank=True, max_length=50, verbose_name='最后登录时间')


Longue interrogation frontale

Pour faciliter la compréhension, le getQrUlr précédent est également collé, ce qui signifie que si l'utilisateur ouvre la page Web, getQrUrl commencera à être exécuté. Ensuite, démarrez la longue méthode loginPoll d'interrogation, je l'ai écrite ici pour les tests, et vous pouvez la modifier vous-même lorsque vous développez.

Code de vue

methods: {
    
    
    getQrUrl() {
    
    
      axios.get('https://api.xxxx.pro/api/weChatLogin').then((res) => {
    
    
        console.log(res.data);
        this.qr_url = res.data.url
        this.scene = res.data.scene
        this.loading = false
      })
      this.tem_poll = setInterval(this.loginPoll, 1000)
    },

    loginPoll() {
    
    
    // 这里就是请求后端的时候顺便带上这个scene
      axios.get('https://api.xxxxx.pro/api/verifyLogin?scene=' + this.scene).then((res) => {
    
    
        console.log(res.data);
        if (res.data == 'success') {
    
    
        // 清除定时器
          clearInterval(this.tem_poll)
          this.$notify({
    
    
            title: '登录成功',
            type: 'success',
            duration: 0
          });
          return;
        }
      })
    }
  }

Code Django

class VerifyLogin(APIView):
    def get(self, request):
    	# 拿到前端给的scene
        scene_str = request.query_params.get('scene')
        # 查询数据库有没有此scene
        tmp_scene_str = User.objects.filter(tmp_scene_str=scene_str)
        print('scene_str-----------{}------------'.format(scene_str))
        print('tmp_scene_str-----------{}------------'.format(tmp_scene_str))
        # 如果有的话就证明这个用户扫码已经关注了,要么是新用户关注进来要么是老用户扫码进来
        if tmp_scene_str:
            print('-------------登录成功!-------------')
            return Response('success')
        # 如果没登陆就一直返回空
        return Response({
    
    })

Si la longue interrogation frontale réussit, la connexion est réussie, puis vers quelle page sauter ou quoi faire, puis faites-le en fonction de l'entreprise.La logique globale n'est pas compliquée, mais le document WeChat est
vague . Si vous souhaitez envoyer des messages à l'avenir, la méthode de publication ci-dessus est utile

Pour envoyer un modèle de message, vous pouvez consulter ce tutoriel

WeChat public account template message push test Python version sans serveur - tutoriel de niveau nounou
https://blog.csdn.net/qq_44718932/article/details/132223216



Toutes les étapes du didacticiel ci-dessus sont terminées. Le front-end utilise l'interface utilisateur Ele.me. Si vous voulez tout le code, vous pouvez le vérifier sur github. Si vous pensez que c'est utile, venez à Sanlian. Pour les commentaires que je ne comprends pas, j'ai ouvert un e-mail de rappel et j'ai répondu quand je l'ai vu

Adresse Github : https://github.com/BioYue/WeChatLogin

Je suppose que tu aimes

Origine blog.csdn.net/qq_44718932/article/details/132316160
conseillé
Classement