Código de escaneo de la cuenta oficial de WeChat para lograr el inicio de sesión en el sitio web-versión Django + Vue-tutorial de nivel de niñera súper detallado


Hay tres formas de realizar el inicio de sesión del código de escaneo de WeChat en la página web:

  • PlanA: plataforma abierta Wechat - se requiere certificación - 300 yuanes
  • PlanB: cuenta pública de WeChat: requiere una cuenta de servicio y ha sido certificada: 300 yuanes
  • PlanC: Miniprogramas de Wechat - Miniprogramas que se han registrado en línea - 0 yuanes

Este tutorial es un ejemplo del inicio de sesión del código de escaneo de la cuenta oficial de WeChat de Django+vue.Desde el inicio de sesión del código de escaneo de WeChat, desde el registro de la cuenta oficial hasta la realización final de todo el proceso, se adjuntará un enlace de github, que es solo un idea básica, y luego haga cambios de acuerdo a su propia situación.Siga el proceso paso a paso, definitivamente se hará realidad. Se enumerarán los detalles.

demo para lograr el efecto final

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí



Este artículo implementa la lógica y el proceso: use el código QR temporal proporcionado por WeChat para volver al front-end y habilite el sondeo largo en el front-end para solicitar el estado de inicio de sesión del back-end. El usuario escanea el código para saltar a la cuenta oficial de WeChat. Si es un usuario nuevo, debe prestar atención. Después de seguir, WeChat volverá a la cuenta oficial. Si es un usuario antiguo, WeChat volverá a la cuenta oficial 新用户登录成功. cuenta 老用户登录成功_ Después de regresar a la cuenta oficial, guarde la información de la credencial clave para el usuario correspondiente. La consulta de sondeo largo de front-end encuentra que la base de datos tiene estos datos, luego devuelve la información del usuario y el inicio de sesión es exitoso. Una vez que finaliza el sondeo largo, el front-end salta para indicar que el inicio de sesión se realizó correctamente.


Solicitar un número de prueba


  • Registrar cuenta pública

El primero es registrar una cuenta oficial de WeChat, solo regístrese casualmente, pero si desea usarla en línea, recuerde solicitar una cuenta de servicio. En cuanto a la diferencia entre la cuenta de servicio y la cuenta de suscripción, no entraré en detalles aquí Si tiene necesidades relevantes, puede ir a la vista oficial de WeChat.

Después de completar el registro, haga clic en 设置与开发la parte inferior del lado izquierdo 接口权限para ver simplemente las categorías de cuentas oficiales requeridas para estas funciones relacionadas. Generalmente, lo que solicitamos es un número individual, que básicamente no tiene funciones, por lo que solo podemos publicar artículos.
inserte la descripción de la imagen aquí

Enlace de registro de cuenta pública
https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN



  • Ingrese el número de prueba

开发者工具Ubicación: debajo de la barra de navegación izquierda公众平台测试账号

inserte la descripción de la imagen aquí

Después de ingresar, se le otorgará un ID de aplicación y un secreto de aplicación , que son parámetros clave y se usarán para realizar pruebas más adelante. Esta información de configuración de la interfaz es la clave para interactuar con el backend de WeChat.

inserte la descripción de la imagen aquí



  • Implementar la información de configuración de la interfaz

inserte la descripción de la imagen aquí

Para interactuar con WeChat, debe configurar la información a través de esta interfaz. Después de completar, haga clic en Enviar para la prueba, y puede continuar con las operaciones posteriores después de pasar la
prueba. Nota:

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

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

Información de configuración de la interfaz enlace original: https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html


Ideas de implementación 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)

Después de completar la URL y el token, haga clic en Enviar. El token que se llenó en la cuenta oficial de WeChat debe ser el mismo que el yue_token en mi código de muestra. Solo copia a los demás. Si se puede acceder a WeChat y verificarlo correctamente con Token





Obtener el código QR con parámetros


Lo anterior es el trabajo de acoplamiento preliminar y luego se describirá el código de la aplicación. Primero, el front-end debe abrir la página para solicitar el código QR para iniciar sesión, y el back-end visita WeChat para obtener el enlace del código QR de acuerdo con la solicitud. Se recomienda leer la documentación. Se debe prestar atención a algunos parámetros y detalles. Si usa Django, puede comprender el significado general mirando mi código directamente.

Generación de código QR con parámetros Enlace original: https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html

Pasos de implementación:

  • Obtener la credencial de llamada de la interfaz global de la cuenta oficial (período de validez 2h) AccessToken
  • Consigue el código QR Ticket
  • URL de empalme de entradas para obtener la URL del código QR
  • Devuelve la escena (utilizada en la última encuesta) y la URL al front-end

codigo 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')

Código 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里面的,打开页面就会执行这个方法

En este momento, la URL obtenida por el front-end es la URL del código QR. Puede hacer clic directamente para ver el código QR y puede incrustarlo en la imagen usted mismo.



Manejar la devolución de llamada del código de escaneo del usuario

Este código QR llevará el boleto y la escena, en cuanto a qué parámetro desea usar como la única credencial para verificar que el inicio de sesión es exitoso. Yo uso escena aquí. Será mucho más conveniente usar el boleto, y el código es demasiado perezoso para cambiarlo. No estaba seguro si el ticket entrará en conflicto con la decisión de concurrencia anterior. Hay muchas impresiones escritas aquí para probar, simplemente elimínelas según sus necesidades.
Debe quedar claro aquí que el método de obtención de la interfaz WeChatSignature que definió se utiliza para la verificación de WeChat, y la publicación es lo que WeChat llamará por usted.
Después de que el usuario escanee el código QR que le diste para iniciar sesión. WeChat devolverá un XML a su servidor. Solo use ET para analizarlo y luego obtenga los parámetros que necesita. He escrito muchos juicios aquí. Puede leer el documento original para comprender el tipo de evento.

Seguir/dejar de seguir el documento original del evento:
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
Documento original del mensaje de respuesta de la cuenta oficial:
https://developers.weixin.qq.com/doc/ offiaccount /Gestión_de_mensajes/Passive_user_reply_message.html#0

Puedes imprimir el xml primero para ver
inserte la descripción de la imagen aquí

codigo 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)

Explique la función del código anterior, que es juzgar la devolución de llamada de WeChat, si es un evento que se ha seguido o no. Vaya a la tabla Usuario para averiguar si existe esta event_key. La event_key que WeChat le devuelve la llamada es la scene_str que definió anteriormente. Pero fíjate que hay una diferencia entre prestar atención y regresar por no seguido, uno tiene un prefijo y el otro no, el documento está escrito, ve y mira, y también se procesa en mi código. Sepa qué usuario inició sesión a través de from_user_name y luego guarde scene_str como una credencial temporal. El xml devuelto a WeChat debe procesarse y analizarse, aquí lo defino en models.py. Este es el método TextMsg y, por cierto, el usuario también se pega. La HttpResponse que se formatea y se devuelve a la cadena se devuelve a la cuenta oficial de WeChat. Sigue la pintura de la calabaza y cámbiala tú mismo. Cuando realice un sondeo frontal posterior, solo necesita averiguar si scene_str existe en la base de datos. Si existe, devuelva los datos de usuario correspondientes a este scene_str al front-end.

modelos.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='最后登录时间')


Sondeo largo de front-end

Para facilitar la comprensión, también se pega el getQrUlr anterior, lo que significa que si el usuario abre la página web, se comenzará a ejecutar getQrUrl. Luego inicie el método loginPoll de sondeo largo, lo escribí aquí para probarlo y puede cambiarlo usted mismo cuando lo desarrolle.

código 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;
        }
      })
    }
  }

codigo 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 el sondeo largo de front-end tiene éxito, el inicio de sesión es exitoso, y luego a qué página saltar o qué hacer, y luego hacerlo de acuerdo con el negocio.La lógica general no es
complicada, pero el documento de WeChat es vago . Si desea enviar mensajes en el futuro, el método de publicación anterior es útil

Para enviar un mensaje de plantilla, puedes echar un vistazo a este tutorial

Mensaje de plantilla de cuenta pública de WeChat Prueba de inserción Versión de Python sin servidor: tutorial de nivel de niñera
https://blog.csdn.net/qq_44718932/article/details/132223216



Todos los pasos del tutorial anterior han terminado. El front-end usa la interfaz de usuario de Ele.me. Si desea todo el código, puede consultarlo en github. Si cree que es útil, venga a Sanlian. Para comentarios que no entiendo, abrí un correo electrónico de recordatorio y respondí cuando lo vi.

Dirección de Github: https://github.com/BioYue/WeChatLogin

Supongo que te gusta

Origin blog.csdn.net/qq_44718932/article/details/132316160
Recomendado
Clasificación