微信公众号扫码登录处理逻辑

项目系统JasmineProject集成了微信扫码功能,在实现的过程中遇到了一些坑, 经过不断尝试,最后实现了此功能,梳理了下大概流程逻辑。

预先处理

  • 已注册有微信公众号。
  • 在微信公众号管理后台可以获取到appId和secrect。
  • 微信消息接口已打通,如何接收微信消息自行查阅,提两点注意的坑。
  • 微信接收消息和校验token为同一地址,get方法为校验token,post方法为消息通知。
  • 配置的通知地址不要漏写 结尾的"/",否则接收不到消息。

   

生成二维码

为前端提供一个生成二维码的接口

    /**
     * 生成公众号二维码
     *
     * @return {ticket,sceneStr}
     */
    @NoTokenCheck
    @GetMapping("wechatQrCode")
    public R<CreateQrScanResp> getQrScan() {
        CreateQrScanResp result = WechatHaoUtil.createQrCode();
        return responseData(result);
    }

之后前端的处理逻辑,有两种方式

轮询方式

  • 前端使用sceneStr轮询后台接口(5秒1次),只要轮询到token,即登录成功。
  • 使用sceneStr 轮询token
  /**
     * 轮询检查 SceneStr 登陆结果
     *
     * @param sceneStr
     * @return
     */
    @NoTokenCheck
    @GetMapping("getTokenBySceneStr")
    public R<String> getTokenBySceneStr(@NotBlank String sceneStr) {
        String token = CodeCache.WECHAT_LOGIN_SCENE_STR_CACHE.get(null, String.class, sceneStr);
        if (token == null) {
            token = "";
        }
        return responseData(token);
    }
  • 使用token完成后续逻辑

实时通知

  • 后台通过webSocket的方式,通知前端登录结果,由于需要额外增加webSocket功能,我们没有使用这种方式

用户扫码

  /**
     * 登录
     *
     * @param wechatMessage
     * @return
     */
    private String processLogin(WechatMessage wechatMessage) {
        String sceneStr = wechatMessage.getEventKey();
        // 已绑定直接登录
        if (userWechatService.isOpenIdBind(wechatMessage.getFromUserName())) {
            // open id 登录
            WechatLoginReq wechatLoginReq = new WechatLoginReq();
            wechatLoginReq.setSceneStr(sceneStr);
            wechatLoginReq.setOpenId(wechatMessage.getFromUserName());

            userService.loginByWechat(wechatLoginReq);

            WechatMessage reply = WechatMessage.builder()
                    .CreateTime(System.currentTimeMillis() / 1000)
                    .FromUserName(wechatMessage.getToUserName())
                    .ToUserName(wechatMessage.getFromUserName())
                    .MsgType(WeChatMessageType.TEXT)
                    .Content("登录成功,2s后自动跳转")
                    .MsgId(CommonUtil.uuid())
                    .build();
            String msg = XmlUtil.toXml(reply);
            return msg;
        }

        // 未绑定  发送绑定页面消息
        WechatMessage reply = WechatMessage.builder()
                .CreateTime(System.currentTimeMillis() / 1000)
                .FromUserName(wechatMessage.getToUserName())
                .ToUserName(wechatMessage.getFromUserName())
                .MsgType(WeChatMessageType.TEXT)
                .Content("您的账户尚未绑定,点击绑定账户菜单完成账户绑定,并重试")
                .MsgId(CommonUtil.uuid())
                .build();
        String msg = XmlUtil.toXml(reply);
        return msg;
    }

openId 已绑定

  • 通过openId绑定获取到我们系统的用户信息,完成登录。
  • 设置 seceneStr- token 缓存,等待前端轮询,后台处理逻辑结束,回复消息登陆成功。

openId 未绑定

  • 回复消息提醒用户绑定,我们尝试过回复一个文章链接消息(跳转绑定页面),但是貌似微信无法打开此链接,遂采用自定义菜单的方式进行绑定。参考文档  网页授权 | 微信开放文档
  • 用户点击绑定菜单,获取用户授权并跳转到绑定页面
  • 自定义菜单的跳转链接为

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9a69e6672c126ce0&redirect_uri=http%3A%2F%2Fjasminesoft%2Ecn%2Fpages%2Flogin%2Ehtml%3FsceneStr%3D18cee13e482146da84cab22ef74c4cf6&scope=snsapi_userinfo&state=123&forcePopup=true#wechat_redirect

其中redirect_uri 为授权成功后的回调地址,注意需要urlEncode ,可以附带参数,但需要吧 '&','?'等符号转义。用户授权成功后会附带一个code参数到回调页面,位于queryString上。

  •  绑定页面逻辑处理
  • 我们使用登录页面处理绑定逻辑,并开发新的页面。
  • 检查到queryString包含code参数,即为绑定逻辑,否则为正常登录逻辑。
  • 用户登录成功后,使用code 和 token 完成微信用户绑定。
    /**
     * 获取微信用户信息然后注册
     *
     * @param weChatRegisterReq {code,token}
     * @return
     */
    @PostMapping("registerWechat")
    public R registerWechat(@RequestBody WeChatRegisterReq weChatRegisterReq) {
        wechatService.registerWechat(weChatRegisterReq);
        return success();
    }
  •  调用网页授权接口获取微信用户信息,使用token获取到我们系统的用户信息,完成绑定
    @Override
    public String registerWechat(WeChatRegisterReq weChatRegisterReq) {
        // 通过code 获取用户信息
        WechatUserInfoResp wechatUserInfoResp = WechatHaoUtil.getUserInfoByCode(weChatRegisterReq.getCode());

        UserWechatAddReq userWechatAddReq = UserWechatAddReq.builder()
                .openId(wechatUserInfoResp.getOpenId())
                .nickName(wechatUserInfoResp.getNickname())
                .avatar(wechatUserInfoResp.getHeadImageUrl())
                .city(wechatUserInfoResp.getCity())
                .province(wechatUserInfoResp.getProvince())
                .country(wechatUserInfoResp.getCountry())
                .sex(wechatUserInfoResp.getSex())
                .unionId(wechatUserInfoResp.getUnionId())
                .build();

        UserWechat userWechat = userWechatService.addOrUpdate(userWechatAddReq);
        return userWechat.getOpenId();
    }

参考截图

  • 微信登录按钮

  • 展示二维码

  • 绑定菜单

 

  • 用户扫描后回复消息

  • 轮询到token后进入系统



JasmineProject 专业的项目管理工具,欢迎大家注册使用!

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flask是一种轻量级的Python Web框架,能够方便地构建网页应用程序。要实现微信公众号扫码关注并登录网页功能,可以使用Flask结合微信开发接口进行实现。 首先,需要在微信公众平台上注册并创建一个公众号,并获取到相关的开发者ID和密钥。 接下来,搭建Flask应用程序,先安装Flask库,并导入相关的依赖库,如wechatpy和requests库等。 然后,创建一个Flask路由,用于接收微信服务器的验证请求和菜单跳转等请求。根据微信开发文档,编写逻辑代码,进行验证和处理微信服务器的各种请求。 在处理菜单跳转请求时,可以通过微信JS-SDK提供的扫一扫功能,生成一个特定的二维码,用于用户关注公众号。二维码中包含一个唯一的标识码,用于识别用户和公众号之间的关系。 当用户扫描二维码关注公众号后,微信服务器会向事先设置的回调URL发送消息通知。在Flask应用程序中,可以通过编写对应的路由来处理该通知,获取到用户的唯一标识码。然后,可以将该标识码与用户相关的信息存储到数据库中,以便后续使用。 最后,通过编写相关的路由和模板,实现用户登录网页功能。当用户点击网页中的登录按钮时,可以跳转到微信授权登录页面。用户授权后,微信会将用户的唯一标识码和相关信息返回到事先设置的回调URL。在Flask应用程序中,处理该回调URL的路由中,可以获取到用户的标识码,从数据库中获取用户信息,并进行登录操作。 综上所述,通过使用Flask框架结合微信开发接口,可以实现微信公众号扫码关注并登录网页功能。这样的实现方式能够方便地与微信公众号进行交互,并提供给用户一个方便、安全的登录方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值