微信公众号开发流程

1、首先注册微信公众号,要根据实际需求考虑清楚应该申请哪一种公众号
以下是官方给出的建议,大家可以多参考参考
1)如果想简单的发送消息,达到宣传效果,建议可选择订阅号;
2)如果想用公众号获得更多的功能,例如开通微信支付,建议可以选择服务号;
3)如果想用来管理内部企业员工、团队,对内使用,可申请企业号;
4)订阅号可通过微信认证资质审核通过后有一次升级为服务号的入口,升级成功后类型不可再变;
5)服务号不可变更成订阅号。
2、自定义菜单设置
自定义菜单官方说明文档地址:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html
我个人使用的是view方式创建菜单,因为后面要获取用户基本信息,做单点登录
1)通过APPID和appsecret获取access_token(有效期是两小时)
接口地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=appsecret
获取access_token示例
注意:获取的时候一定要当前获取的服务器ip添加相应的白名单,如下图:
白名单设置
2)拿到access_token后,调用创建菜单地址
创建菜单地址:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=access_token
创建菜单示例图
3)查询自己创建的菜单
查询菜单地址:https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=access_token
查询菜单接口

3、后台对接微信用户基本信息(java)
1)查看接口权限中网页授权说明,可以清晰看到需要4步,如下:
网页授权步骤图
2)上述4步中的第一步,获取code:
前端第一步用下图中的地址获取code,其中的scope、redirect_uri最为重要,一个是获取用户基本信息的权限,一个是微信端跳转到你登录页面,然后会带入code和state字段给我们的页面,如果地址没问题,code会在返回的url中,通过截取可以获得。
单点第一步
3)写后端接口,通过code换取网页授权access_token
Controller层

/**
     * @Description 微信的单点登录
     * @author xkh
     * @date 2021-9-31 10:27
     * @param code 票据
     * @return com.sx.common.result.RestResponse
     */
    @PostMapping(value = "/login", produces = "application/json; charset=utf-8")
    @ApiOperation(value = "登录授权", notes = "登录授权", produces = "application/json; charset=utf-8")
    @ApiImplicitParam(name = "code", value = "code作为换取access_token的票据", required = true, dataType = "string", paramType = "query")
    public RestResponse login(@RequestParam(name = "code", required = true) String code, HttpServletRequest request, HttpServletResponse response) {
        return ResultGenerator.genSuccessResult(sysWxUserService.login(code, request, response));
    }


    实现层代码:
```/**
     * @param code 票据
     * @return com.sx.system.vo.WxUserVO
     * @Description 微信的单点登录
     * @author xkh
     * @date 2021-9-31 10:46
     */
    @Override
    public WxUserVO login(String code, HttpServletRequest request, HttpServletResponse response) {
        //TODO 1、先通过code获取access_token和openid
        Map<String, Object> params = new HashMap<>();
        String url = WxCommonConstants.GET_ACCESS_TOKEN_URL;
        //这种引用就不需要其他系统必须的,使用该功能再配置
        String appId = GlobalConfig.getConfig("wx.appid");
        String appSecret = GlobalConfig.getConfig("wx.appsecret");
        params.put("appid", appId);
        params.put("secret", appSecret);
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        JSONObject jsonObject = JSONObject.parseObject(HttpClientUtil.doHttpsGet(url, params));
        if (StringUtil.isNotEmpty(jsonObject.get("errcode"))) {
            throw new SxException((Integer) jsonObject.get("errcode"), (String) jsonObject.get("errmsg"));
        }
        /**
         * {
         *   "access_token":"ACCESS_TOKEN",
         *   "expires_in":7200,
         *   "refresh_token":"REFRESH_TOKEN",
         *   "openid":"OPENID",
         *   "scope":"SCOPE"
         * }
         */
        log.info("通过code换取access_token、openID:{}", jsonObject);
        String accessToken = (String) jsonObject.get("access_token");
        String openId = (String) jsonObject.get("openid");
        if (StringUtil.isEmpty(accessToken) || StringUtil.isEmpty(openId)) {
            throw new SxException(GovernExceptionEnum.WXUSER_OPENID_NOT_EXIST);
        }
        //TODO 2、通过access_token拉取用户信息(需scope为 snsapi_userinfo)
        String lang = GlobalConfig.getConfig("wx.lang");
        url = WxCommonConstants.GET_SNS_USER_INFO_URL;
        params = new HashMap<>();
        params.put("access_token", accessToken);
        params.put("openid", jsonObject.get("openid"));
        params.put("lang", lang);
        jsonObject = JSONObject.parseObject(HttpClientUtil.doHttpsGet(url, params));
        log.info("微信用户信息:{}", jsonObject);
        //TODO 3、查询数据库微信用户信息、保存或者更新用户信息
        SysWxUser sysWxUser = sysWxUserMapper.selectByOpenId((String) jsonObject.get("openid"));
        if (null == sysWxUser) {
            //新增用户信息
            sysWxUser = new SysWxUser();
            sysWxUser.setOpenId((String) jsonObject.get("openid"));
        }
        saveOrUpdateWxUser(sysWxUser, jsonObject);

        String affiliationApp = request.getHeader(SystemCommonConstants.AFFILIATIONAPP_KEY);
        String affiliationAppType = request.getHeader(SystemCommonConstants.AFFILIATIONAPPTYPE_KEY);
        if (StringUtils.isEmpty(affiliationApp) || StringUtils.isEmpty(affiliationAppType)) {
            throw new SxException(SysExceptionEnum.AFFILIATIONAPP_OR_AFFILIATIONAPPTYPE_EMPTY);
        }

        // 设置RefreshToken,时间戳为当前时间戳,直接设置即可(不用先删后设,会覆盖已有的RefreshToken)
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        StringBuilder key = new StringBuilder();
        key.append(CommonConstant.PREFIX_SHIRO_REFRESH_TOKEN)
                .append(sysWxUser.getId())
                .append(SymbolConstants.COLON)
                .append(affiliationApp)
                .append(SymbolConstants.COLON)
                .append(affiliationAppType);
        redisUtil.setValue(key.toString(), currentTimeMillis, refreshTokenExpireTime);
        //把用户设置到redis中,不需要重复查询
        redisUtil.setValue(CommonConstant.PREFIX_SHIRO_WXUSER + sysWxUser.getId(), sysWxUser, refreshTokenExpireTime);
        // 从Header中Authorization返回AccessToken,时间戳为当前时间戳
        String token = JwtUtil.sign(String.valueOf(sysWxUser.getId()), currentTimeMillis, affiliationApp, affiliationAppType);
        response.setHeader("Authorization", token);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");

        WxUserVO wxUserVO = new WxUserVO();
        BeanUtils.copyProperties(sysWxUser, wxUserVO);
        wxUserVO.setMobilePhone(sysWxUser.getMobilPhone());
        if (StringUtil.isNotEmpty(sysWxUser.getAreaId())) {
            //TODO 用户选择的地区名称
            SysArea sysArea = sysAreaMapper.selectById(sysWxUser.getAreaId());
            if (null != sysArea) {
                wxUserVO.setAreaName(sysArea.getName());
            }
        }
        //异步保存微信登录流水
        sysWxUserLogService.asyncSaveLog(sysWxUser);
        Integer areaId = StringUtils.isEmpty(sysWxUser.getAreaId()) ? null : Integer.valueOf(sysWxUser.getAreaId());
        hstLoginStatisService.saveInfo(sysWxUser.getId(), sysWxUser.getUserName(), areaId, CommonConstants.STRING_30);
        return wxUserVO;
    }
```java

4)刷新access_token(如果需要)
这步可以不需要,暂不做描述
5)拉取用户信息(需scope为 snsapi_userinfo)
地址:http:GET(请使用https协议) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
本人在上述第三步中已经调用
调用获取用户说明

可用微信开发者工具调试,实际调试结果如下:
调试结果

最后实际调试的采坑点记录:
1、后台重定向地址以及设置菜单的appid是测试公众号的appID,不是个人的,测试公众号在"开发者工具"–>“公众平台测试账号”–>里面含有appId和appsecret
2、设置JS接口安全域名 183.129.166.58:8999/
3、设置"网页服务"–>“网页账号”–>“网页授权获取用户基本信息”–>“授权回调页面域名:”: 183.129.166.58:8999

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值