Express实战个人订阅号实现网站登录

科技资讯 投稿 6700 0 评论

Express实战个人订阅号实现网站登录

express 。其它框架原理基本一致,只是定义路由或返回响应数据部分代码跟 express 有所出入。先来一波效果图:

1. 前言

express 开发微信公众号的案例: 原文地址。当时使用的 nodejs 版本还是 v8.x,现如今,nodejs 的最新长期稳定版已经来到了 v18.16.0, 新特性尝鲜版更是已经到了 v20.1.0

.....。

2. 为何要用订阅号去登录

    手机号验证码注册
  • 第三方登录(支持微信扫码、微博、Github

企业站来说,这种方式固然好,给了用户提供了更多的选择。

手机号接收验证码注册:1 条短信 1 毛钱,10 条就是 1 块,100 条就能吃个豪华早餐了

Github 倒是不需要,不过接入也麻烦,弃之!

那就普通的注册吧?填写用户名、密码、确认密码、输入邮箱,邮箱验证码确认?弃!

用户只需关注公众号,反手输入个登录,回车!Ctrl + CV。欸,很快啊,登录成功!

而且,且看下图,它对于保护用户隐私来说,是极好的,因为开发者只能拿到用户的 OpenID,头像和昵称都不给你!

OpenID 就足够了,毕竟它对于当前公众号来说,是 唯一的

3. 公众号后台配置

进入微信公众平台

设置与开发 -> 基本配置 -> 服务器配置(未开启的需要先开启

    URL 是你的后端服务对应验证授权的接口地址,也就是你后端服务部署后绑定了域名的接口地址。举例: https://www.xxx.com/wechat

  • Token 这块的 Token 按照平台提示的规则自定义即可,注意,需要和上面代码中的 Token 相对应,不然会验证不成功。

  • EncodingAESKey 是消息加解密密钥,这个可以随机生成,也可以自定义

  • 消息加解密方式 选择明文模式即可

先不必急着点击提交,因为这个时候服务还没部署,服务器是无法正常响应微信服务器的验证请求,必然会提交失败。

4. 登录流程梳理

我们简单的梳理一下登录流程:

  1. 后台接收到用户请求,判断用户发送的内容的确是 "登录" 关键字,返回一个验证码给用户,并将当前验证码存起来

5. 定义服务端路由,处理验证逻辑及服务端部署

5.1 定义授权验证接口

主要是验证消息的确来自微信服务器

import express from "express";
import jsSHA from "jssha";
const router = express.Router(;
router.get("/wechat_mp", (req, res, next => {
  const token = "这里是自定义Token,可自定义,内容规则详见下文";
  //1.获取微信服务器Get请求的参数 signature、timestamp、nonce、echostr
  const { signature, timestamp, nonce, echostr } = req.query;

  //2.将token、timestamp、nonce三个参数进行字典序排序
  const array = [token, timestamp, nonce].sort(;

  //3.将三个参数字符串拼接成一个字符串进行sha1加密
  const tempStr = array.join("";
  const shaObj = new jsSHA("SHA-1", "TEXT";
  shaObj.update(tempStr;
  const scyptoString = shaObj.getHash("HEX";

  //4.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
  if (signature === scyptoString {
    console.log("验证成功";
    res.send(echostr;
  } else {
    console.log("验证失败";
    res.send("验证失败";
  }
};

5.2 处理用户 "登录" 消息

接下来我们定义用户发送消息的逻辑:

XML格式 的参数去请求这个接口,只不过这个时候,我们需要通过 POST 请求来接收参数。

定义POST接口
import { parseString } from "xml2js";
import myCache from "../store";
/**
 * 随机6位验证码
 */
function randomCode( {
  return Math.random(.toString(.slice(-6;
}
/**
 * 回复文字消息封装
 */
function sendTextMsg(toUser, fromUser, content {
  let resultXml = "<xml><ToUserName><![CDATA[" + fromUser + "]]></ToUserName>";
  resultXml += "<FromUserName><![CDATA[" + toUser + "]]></FromUserName>";
  resultXml += "<CreateTime>" + new Date(.getTime( + "</CreateTime>";
  resultXml += "<MsgType><![CDATA[text]]></MsgType>";
  resultXml += "<Content><![CDATA[" + content + "]]></Content></xml>";
  return resultXml;
}
router.post("/wechat_mp", function (req, res {
  var buffer = [];
  req.on("data", function (data {
    buffer.push(data;
  };
  // 内容接收完毕
  req.on("end", function ( {
    var msgXml = Buffer.concat(buffer.toString("utf-8";
    parseString(msgXml, { explicitArray: false }, function (err, result {
      if (err throw err;
      result = result.xml;
      const { ToUserName, FromUserName, MsgType, Content } = result;
      if (MsgType === "text" && Content === "登录" {
        const code = randomCode(;
        // 这里的FromUserName就是用户的OpenID
        myCache.set(code, FromUserName, 1 * 60 * 5;
        const sendXml = sendTextMsg(
          ToUserName,
          FromUserName,
          `您的登录验证码是:${code}  ,  有效期为5分钟`
        ;
        res.send(sendXml;
      }
    };
  };
};
store/index.js
import NodeCache from "node-cache";
const myCache = new NodeCache(;
export default myCache;

代码解释:

    xml2js 这个库来解析 XML 格式的参数

  • 消息类型 为 text 且内容为 登录 关键字的时候,我们去生成一个 6位随机验证码,再将验证码和用户的 OpenIDkey(code)、value(OpenId 的格式存入 存入 node-cache 中,并设置有效期为 5分钟,同时将随机验证码发送给用户。

5.3 处理网站登录逻辑

定义验证码校验接口

import myCache from "../store";
router.get("/verify", async function (req, res {
  const { code } = req.query;
  const OpenID = myCache.get(code;
  if (OpenID {
    const token = "使用OpenID进行jwt鉴权颁发Token";
    res.json({
      code: 200,
      data: { token },
    };
  } else {
    res.json({
      code: 400,
      msg: "您输入的验证码有误或已过期,请重新输入!-_-",
    };
  }
};

代码解释:

node-cache 中获取 OpenID,如果存在,则说明验证码正确,jwt 鉴权颁发 Token。反之,校验失败。

OpenID 和自定义的 secret 给用户颁发 Token,用户再次访问网站的时候,只需要携带 Token 即可进行鉴权。

jwt 鉴权概念、流程及使用,大家可以参考这条 AI 问答分享:


我在ChatGPTer(https://ai.iiter.cn网站上创建了一个AI对话分享,快来看看吧!

「jwt鉴权概念、流程」

链接:https://ai.iiter.cn/#/share/6465c5a2e82a696c417bbfa9

同时,也欢迎大家自己进行 AI 问答: https://ai.iiter.cn

5.4 部署服务

当然,您也可以使用自己顺手的部署方式

5.5 提交公众号配置

公众号后台配置 部分,点击提交即可

结语

而且在给用户提供服务的同时,可以直接将用户引导至自己的公众号上。不管是后面对网站的更新记录,还是一些重要的通知,都可以通过公众号进行消息推送,一举两得

正式给大家介绍一下:

OpenAI 的 API 开发的一款 ChatGPT 网站,模型是gpt-3.5-turbo,使用的是本篇文章的同款登录方式,欢迎大家体验

编程笔记 » Express实战个人订阅号实现网站登录

赞同 (32) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽