一图讲清楚公众号扫码关注绑定手机号自动登录

讲清楚,公众,关注,绑定,手机号,自动,登录 · 浏览次数 : 422

小编点评

内容生成时需要带简单的排版,如下: 1. **标题**:以简单易懂的标题代替,例如 "公众号扫码关注绑定手机号自动登录流程" 2. **概述**:简短地概括内容的主题,例如 "公众号扫码关注绑定手机号自动登录流程" 3. **内容**:以清晰易懂的语言描述内容,例如 "公众号扫码关注绑定手机号自动登录流程,以避免手动输入手机号码" 4. **排版**:以简单的排版方式排列内容,例如 "标题,概述,内容,排版" 5. **结尾**:以简单易懂的结尾代替,例如 "关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!" 6. **图片**:在内容中添加图片,以增强用户体验,例如 "公众号扫码关注绑定手机号自动登录流程,图片展示用户扫码自动登录流程" 7. **代码**:在内容中添加代码,例如 "获取用户 token",以增强用户体验,例如 "获取用户 token,代码展示如何获取用户 token" 8. **排版**:以简单的排版方式排列内容,例如 "标题,概述,内容,排版" 9. **格式**:以统一的格式编写内容,例如标题、概述、内容、排版等 10. **排版**:以简单的排版方式排列内容,例如 "标题,概述,内容,排版"

正文

日常开发中,相信不管做 C 端还是 B 端业务的同学都会遇到微信相关的业务,比如微信登录、微信支付、公众号扫码关注等场景。

最近博主在做公众号扫码关注自动登录这一块的业务,因此总结绘制了一张公众号扫码关注绑定手机号自动登录流程图分享给大家。

扫码关注绑定手机自动登录

推荐博主开源的 H5 商城项目waynboot-mall,这是一套全部开源的微商城项目,包含三个项目:运营后台、H5 商城前台和服务端接口。实现了商城所需的首页展示、商品分类、商品详情、商品 sku、分词搜索、购物车、结算下单、支付宝/微信支付、收单评论以及完善的后台管理等一系列功能。 技术上基于最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中间件。分模块设计、简洁易维护,欢迎大家点个 star、关注博主。

github 地址:https://github.com/wayn111/waynboot-mall

1. 准备工作

想要达到用户扫描二维码打开微信公众号主页并且关注后自动登录,目前只能通过接入公众号的服务器配置来完成,下面介绍下前置准备。

  1. 注册微信公众平台服务号(注意:不要注册成订阅号!因为生成带参数的二维码这个接口只有服务号能调用)

  2. 开通微信认证(注意:微信认证每年需要交 300 块钱),如下图展示即可认为前两步配置已完成。

  3. 进入公众号后管【设置与开发】-【基本设置】,点击开发者密码(AppSecret)启用,拿到 appId、secret

  4. 部署服务端代码(需公网,因为第五步的服务器地址需要公网才能验证通过)

    • 准备公网服务器一台。
    • 下载 weixin-java-mp-demo 项目代码,地址:https://github.com/binarywang/weixin-java-mp-demo。
    • 按照 readme 文档说明,修改 yml 文件的 appId、secret 为第二步中的 appId、secrettoken、aesKey 等第五步设置完替换,如下是 weixin-java-mp-demo 项目的使用步骤。 weixin-java-mp-demo使用步骤
    • 将 weixin-java-mp-demo 部署到公网服务器上就 ok 了。
  5. 进入公众号后管【设置与开发】-【基本设置】,点击服务器配置启用后,填写相关的服务器地址、令牌、消息加解密密钥、消息加解密方式,点击提交等待服务器地址验证通过后即完成了所有前置准备工作。

ps: 公众号接入服务器配置后,以前设置的自动回复和自定义菜单就失效了,后续自定义菜单只能通过调用公众号的api接口来进行设置,自动回复则需要在 weixin-java-mp-demo 项目的事件接收代码中进行回复。

2. 扫码关注自动流程

现在我们基于公众号内提供的 api 来完成扫码关注自动登录的操作,流程如下,

2.1 客户端流程

  1. 用户打开网页、TV 端时请求服务端接口获取公众号二维码以及用户标识。
  2. 根据用户标识轮询用户扫码状态接口,获取用户是否注册信息。
  3. 用户扫码后如果是已注册就根据轮询接口返回的 token 进行登录。
  4. 用户扫码后如果是未注册就弹出绑定手机号弹窗,当用户绑定成功根据绑定接口返回的 token 进行登录。

2.2 服务端流程

服务端需要提供三个接口以及监听扫码事件来获取用户 openId 并以此判断该扫码用户是否注册。

  1. 生成带参数的二维码以及用户标识接口,生成带参数的二维码主要根据公众号提供的接口文档中生成带参数的二维码这个接口,以此当用户扫码后点击关注,服务端便可以接收到用户的关注事件。如果是已关注用户扫码,服务端就会接收到扫码事件,下面是生成参数二维码后的扫码事件相关说明。

  2. 用户扫码状态轮询接口,轮询接口需要返回三个基本状态。状态一继续轮询,状态二未注册提示绑定手机,状态三已注册就返回 token 进行登录,是否注册的判断需要在接收到关注扫码事件时根据 openId 去数据库中查询用户的注册状态。

  3. 用户扫码关注后,服务端接收到相关事件,根据 openId 判断用户是否已注册,已注册就将轮询接口设置为已注册,并生成用户token。未注册就将轮询接口设置为未注册,提示绑定手机。

  4. 绑定手机号接口,到了绑定手机号接口就相对独立一些,不在依赖公众号相关接口以及事件通知,绑定成功返回用户登录 token 即可。

2.3 用户扫码流程

用户扫码流程只有用户扫码的动作。

  1. 扫码后未关注时,只有用户点击关注按钮,服务端就会收到关注事件。
  2. 扫码后已关注,服务端就会收到扫码事件。

3. 代码示例

3.1 生成带参数二维码

@PostMapping("userQrcodeCreate")
private Result<WeixinQrcodeResponseVO> userQrcodeCreate(@RequestBody @Validated WeixinMPRequestVO req) {
    log.info("========================userQrcodeCreate begin, req:{}========================", req);
    WeixinQrcodeResponseVO weixinQrcodeResponseVO = new WeixinQrcodeResponseVO();
    try {
        if (!this.wxMpService.switchover(properties.getCurAppid())) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", properties.getCurAppid()));
        }
        String sceneType = req.getSceneType();
        String uuid = IdUtil.fastSimpleUUID();

        // 临时ticket
        WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneType + WEIXIN_MP_SCENCE_SPLIT + uuid, WEIXIN_MP_USER_STATUS.getExpireTime());
        String showQrCodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket());
        Response response = HttpToolUtil.getRequest(showQrCodeUrl);
        if (!response.isSuccessful()) {
            return ResultUtil.error(ErrorCode.WEIXIN_CREATE_QRCODE_ERROR);
        }
        try (InputStream inputStream = response.body().byteStream()) {
            String base64 = ImageUtil.imgToBase64(inputStream, "image/jpg");
            weixinQrcodeResponseVO.setImgBase64str(base64);
            weixinQrcodeResponseVO.setUuid(uuid);
            // 设置开始轮询
            redisUtil.set(WEIXIN_MP_USER_STATUS.getKey(uuid), UserSanLoopStatusEnum.LOOP.getType(), WEIXIN_MP_USER_STATUS.getExpireTime());
        }
    } catch (Exception e) {
        log.error("创建场景二维码失败", e);
        return ResultUtil.error(ErrorCode.WEIXIN_CREATE_QRCODE_ERROR);
    }
    Result<WeixinQrcodeResponseVO> success = ResultUtil.success(weixinQrcodeResponseVO);
    log.info("userQrcodeCreate end, resp:{}", success);
    return success;
}

3.2 扫码后轮询

// 轮询状态枚举
public enum UserSanLoopStatusEnum {
    /**
     * 已过期
     */
    EXPIRED(1),
    /**
     * 继续轮询
     */
    LOOP(2),
    /**
     * 已注册
     */
    REG(3),
    /**
     * 未注册
     */
    NOT_REG(4),
    ;
}

// 开始轮询
public WeixinUserStatusResponseVO userStatus(WeixinMPRequestVO req) {
    String uuid = req.getUuid();
    String source = req.getSource();
    String openId = (String) redisUtil.get(WEIXIN_MP_USER_OPENID.getKey(uuid));
    WeixinUserStatusResponseVO weixinUserStatusResponseVO = new WeixinUserStatusResponseVO();
    Object value = redisUtil.get(WEIXIN_MP_USER_STATUS.getKey(uuid));
    if (value == null) {
        return weixinUserStatusResponseVO.setStatus(UserSanLoopStatusEnum.EXPIRED.getType());
    }
    Integer status = (Integer) value;
    // 如果用户扫码是已注册,就直接根据openId获取用户token
    if (status.equals(UserSanLoopStatusEnum.REG.getType())) {
        String token = getToken(openId);
        weixinUserStatusResponseVO.setToken(token);
    }
    return weixinUserStatusResponseVO.setStatus(status);
}

3.3 关注事件处理

@Component
public class SubscribeHandler extends AbstractHandler {
    @Autowired
    private ScanScenesHandler scanScenesHandler;
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                    Map<String, Object> context, WxMpService weixinService,
                                    WxSessionManager sessionManager) throws WxErrorException {
        String openId = wxMessage.getFromUser();
        this.logger.info("根据openid判断用户是否已注册" );
        WxMpXmlOutMessage responseResult = null;
        try {
            responseResult = scanScenesHandler.handleSpecial(wxMessage, userWxInfo);
        } catch (Exception e) {
            this.logger.error(e.getMessage(), e);
        }
        ...
        return null;
    }
}

3.3 扫码事件处理

@Component
public class ScanHandler extends AbstractHandler {
    @Autowired
    private ScanScenesHandler scanScenesHandler;
    @Autowired
    private WeixinMpMsgReplyService weixinMpMsgReplyService;
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> map,
                                    WxMpService weixinService, WxSessionManager wxSessionManager) throws WxErrorException {
        String openId = wxMessage.getFromUser();
        this.logger.info("根据openid判断用户是否已注册" );
        WxMpXmlOutMessage responseResult = null;
        try {
            responseResult = scanScenesHandler.handleSpecial(wxMessage, userWxInfo);
        } catch (Exception e) {
            this.logger.error(e.getMessage(), e);
        }
        ...
        return null;
    }
}

总结

自此,本文所讲述的公众号扫码关注绑定手机号自动登录流程就讲解完毕了。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

与一图讲清楚公众号扫码关注绑定手机号自动登录相似的内容:

一图讲清楚公众号扫码关注绑定手机号自动登录

日常开发中,相信不管做 C 端还是 B 端业务的同学都会遇到微信相关的业务,比如微信登录、微信支付、公众号扫码关注等场景。 最近博主在做公众号扫码关注自动登录这一块的业务,因此总结绘制了一张**公众号扫码关注绑定手机号自动登录**流程图分享给大家。 ![扫码关注绑定手机自动登录](https://p

[转帖]数据可视化之redash(支持43种数据源) (转自https://anjia0532.github.io/2019/07/08/redash/)

https://www.cnblogs.com/a00ium/p/13177272.html 人类都是视觉动物,讲究一图胜千言。如果没了可视化,那么你在跟领导汇报工作时,很大程度会鸡同鸭讲。其实 excel2016+已经是一个不错的数据分析及可视化工具了(支持几十种数据源),但是,不方便权限控制,集

使用腾讯元宝+markmap生成思维导图

AI可以帮助我们进行提炼和总结, 节省了大量搜索资料和查阅的时间,像上图这张思维导图,就是使用腾讯元宝大模型进行内容提炼,再使用markmap生成思维导图,下面讲解下详细实现步骤: 一、工具准备 腾讯元宝,腾讯出口的大语言模型,让他进行主题的提炼并生成我们想要的特定格式,访问地址:https://y

Azure Data Factory(八)数据集验证之服务主体(Service Principal)

一,引言 如下图所示,今天我们接着上一篇内容,继续讲解 Azure Data Factory 中的数据集连接服务的认证方式:Service Principal 关于 Service Principal 的创建 可以参考:Azure AD(四)知识补充-服务主体 至于需要给 Service Princ

PerfView专题 (第十六篇): 如何洞察C#托管堆内存的 "黑洞现象"

## 一:背景 ### 1. 讲故事 首先声明的是这个 `黑洞` 是我定义的术语,它是用来表示 `内存吞噬` 的一种现象,何为 `内存吞噬`,我们来看一张图。 ![](https://img2023.cnblogs.com/blog/214741/202307/214741-202307241003

#PowerBi Superchange PowerBi 序言部分笔记(2)

Xmind本文思维导图 序言部分,主要讲述了BI的分类及发展,以及作者推荐的学习方法。重点是介绍了powerbi的主要四大步骤。 即: 一:数据采集 Data acquisition: Power BI has a powerful data acquisition engine that help

C# 托管堆 遭破坏 问题溯源分析

一:背景 1. 讲故事 年前遇到了好几例托管堆被损坏的案例,有些运气好一些,从被破坏的托管堆内存现场能观测出大概是什么问题,但更多的情况下是无法做出准确判断的,原因就在于生成的dump是第二现场,借用之前文章的一张图,大家可以理解一下。 为了帮助更多受此问题困扰的朋友,这篇来整理一下如何 快狠准 的

Dive into TensorFlow系列(1)-静态图运行原理

接触过TensorFlow v1的朋友都知道,训练一个TF模型有三个步骤:定义输入和模型结构,创建tf.Session实例sess,执行sess.run()启动训练。不管是因为历史遗留代码或是团队保守的建模规范,其实很多算法团队仍在大量使用TF v1进行日常建模。我相信很多算法工程师执行sess.run()不下100遍,但背后的运行原理大家是否清楚呢?不管你的回答是yes or no,今天让我们一

[转帖]JVM系列之:你知道Java有多少种内存溢出吗

本文为《深入学习 JVM 系列》第二十五篇文章 Java内存区域 关于这部分内容大多来源于《深入理解Java虚拟机》一书。 Java 运行时数据区域(JDK8)如下图所示: 关于上述提到的线程共享和线程隔离区域,下图做详细讲解: 程序计数器 程序计数器是一块较小的内存空间,可以看作是当前线程所执行的

[转帖]水晶头超5类和6类的区别是什么?六类水晶头和超五类水晶头通用吗?

一图胜千言,5类水晶头和6类水晶头从外观上看并没有很大的区别,但实际上里面还是有很大的不同。 5类水晶头的8根线芯是一字排开的,而6类水晶头的8根线芯是呈现上、下交错的形式排列。 原因其实特别简单,标准的超五类网线线径是0.51mm,六类网线的线径是0.57mm,超六类网线的线径是0.58mm。 那