微信服务号网页开发教程

2021年08月29日 99 字 教程整理


0.1. 公众号注册与维护

0.1.1. 公众号的分类及简介

微信公众号包含【订阅号】、【服务号】和【企业号】三种类型的账号。

0.1.1.1. 微信订阅号

订阅号主要偏于为用户传达资讯信息,每天可以群发1次消息,同样每次最多8条图文消息,消息显示在“订阅号”文件夹中,部分支持高级接口能力和微信支付—商户功能。目前是应用最多的公众号。类似于:骑行西藏、央视新闻都是订阅号。
订阅号适用于个人、媒体、企业、政府或其他组织,优点在于每天可群发1次消息,部分支持每天群发多次消息,缺点就是部分接口权限较少;另外,订阅号推送的信息与服务号的展示方式不同:所有的订阅号都被折叠到一起,共同挤在一个叫“订阅号”的文件夹中。
订阅号是可以升级成服务号的,但这个过程是不可逆的;也就是说,服务号不可再转成订阅号。

0.1.1.2. 微信服务号

服务号主要偏于服务交互,为企业和组织提供更强大的业务服务与用户管理能力;功能类似:12315、114、招商银行;提供绑定信息,服务交互,商户功能(微信支付)等。

服务号每个月可以群发4次消息,每次最多8条图文消息,消息直接显示在好友对话列表中,拥有高级接口能力,可以依据接口开发出更多优质功能。不可注册为个人,适用于媒体、企业、政府或其他组织,优点在于功能接口多,群发消息显示好友对话列表,最大的缺点就是每个月只能群发4次。

综上所述,基于微信公众平台生态的开发,如有功能扩展或高级功能接入(如: 微信支付,微信红包等)的预期,建议选择使用【微信服务号】进行开发。

0.1.1.3. * 微信企业号(企业微信)

企业号主要用于公司内部通讯使用,需要先验证身份才可以关注成功企业号。在微信公众平台V5.0及更高版本中,企业微信号已变更为【企业微信】。

根据一些常见运营场景的比对,整理出微信订阅号与服务号的细节差异如下:

功能权限 订阅号 服务号
未认证 已认证 未认证 已认证
基本定位 用户/引流/流量 客户/营销/内容
是否显示/留存在订阅者通讯录 否 (存放于订阅者【订阅号】文件夹)
推送消息时,订阅用户消息提醒
推送消息显示位置 订阅者【订阅号】文件夹 订阅者聊天列表
群发数量上限 1条/天 4条/月
高级功能_自定义菜单 不支持 支持 不支持 支持
高级功能_自动回复菜单 不支持 支持 不支持 支持
高级功能_商户功能(微信支付) 不支持 不支持 不支持 支持
高级功能_红包 不支持 不支持 不支持 支持
高级功能_网页授权(开发) 不支持 不支持 不支持 支持
高级功能_获取用户的身份标识 不支持 不支持 不支持 支持
高级功能_高级/精细化群发 不支持 不支持 不支持 支持
高级功能_带参二维码 不支持 不支持 不支持 支持
高级功能_模板消息 不支持 不支持 不支持 支持
高级功能_长链接转短链接 不支持 不支持 不支持 支持
高级功能_客服接口 不支持 不支持 不支持 支持
高级功能_个性化/差异化菜单接口 不支持 不支持 不支持> 支持
高级功能_… 不支持 不支持 不支持 支持>

0.1.2. 订阅号/服务号的注册

进入微信公众平台:https://mp.weixin.qq.com/,选择需要注册的公众号类型,填写好邮箱即可完成初步注册。

注册完成后,需补充登记相关信息,完成认证:

0.1.3. 服务号的维护

公众号的维护有两种模式:【编辑模式】和【开发模式】。

0.1.3.1. 编辑模式

【编辑模式】可以设置自动回复信息/自定义菜单/页面模板等相关功能,直接使用微信公众平台所提供的后台操作进行用户交互:

编辑模式可以使用在如下的场景:

  1. 不具备开发能力的运营者;
  2. 主要进行品牌宣传、新闻媒体、自助客服的公众账号;
  3. 运营初期,不需要特别多的功能;
  4. 开发模式系统升级、故障等特殊情况。

编辑模式主要包含:消息群发、自定义菜单、自动回复等模板化功能。

0.1.3.2. 开发模式

【开发模式】即直接使用接口代码实现用户的交流。
【编辑模式】配置及响应速度较快,但相对复杂的功能不便于扩展,也没有数据库对这些配置进行管理。
如需对接数据库或实现更多的功能扩展,可以选用【开发模式】,自行搭建服务器并开发相关API。

【注】在开启【开发模式】的同时,【编辑模式】中部分功能则不能正常使用。即开发者模式跟编辑模式存在冲突。因此在切换两个模式的时候,要注意对之前设置的重新测试和验证。

0.1.3.3. 公众号的手机端控制

如果需要用手机执行公众号信息推送功能,可以通过【公众平台安全助手】来实现。

0.2. 公众号开发信息及接口权限配置(网页授权方式)

0.2.1. 基础开发信息配置:APPID、AppSecrect和IP白名单

APPID和AppSecret是开发必须用到的信息。其中AppSecret只有初始化或重置的时候是可见的,要备份好且注意保护,不可随意外发。如有遗忘可以重置。

APPID是公众号开发识别码,配合AppSecret可调用公众号的接口能力。

AppSecret是校验公众号开发者身份的密码,具有极高的安全性。因此切勿将AppSecret直接交给第三方开发者或直接存储在代码中。如需第三方代开发公众号,请使用授权方式接入。

IP白名单也是一个很重要的配置。通过APPID及AppSecret调用获取access_token接口时,需要设置访问来源IP为白名单。
微信为了提高公众平台开发者接口调用的安全性,避免一旦开发者ID和密码泄露后给帐号造成损失,对调用【获取access_token】接口增加IP白名单校验:只有将服务的IP地址设置为公众号的IP白名单,才能成功调用该接口。

0.2.2. 公众号设置: OAuth2.0网页授权(回调)域名 (redirect_uri )

用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息。也就是通过这种授权机制,我们能获取微信用户信息,比如:头像、昵称、地区、个性签名等。利用这些用户信息,我们可以实现一些业务逻辑,比如来源统计、帐号绑定、用户身份鉴权等功能。

这个授权的流程可以简单描述为:

  1. 用户打开微信应用环境,进入公众号;
  2. 在公众号中打开相关的公众号应用(如:H5/小程序等)的网页授权url链接 (格式通常为:https://open.weixin.qq.com/connect/oauth2/authorizeappid=<APPID>&redirect_uri=<REDIRECT_URI>&response_type=code&scope=<SCOPE>&state=<STATE>#wechat_redirect ),触发认证地址 ;
  3. 微信后台收到用户授权许可,生成授权码(code )。随后将授权码作为参数回调至项目配置指定的一个授权页面;
  4. 被重定向的应用回调页面接收微信后台发来的授权码(code ),并通过微信官方提供的access token api接口获取access token;
  5. 最后通过access token以及微信官方提供的另一个userinfo api接口就能获取到用户的微信账号信息。

微信的网页授权是基于OAuth2.0协议的。
百科上对OAuth的介绍是:OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如头像,个人信息等),而无需将用户名和密码提供给第三方应用;而OAuth2.0则是OAuth协议的升级版,但并不兼容老版本。实际上,现在很多企业都使用到OAuth2.0,比如支付宝,微信,QQ授权登录等等。

网页授权信息通常在这里配置:

【注】这里可以看到,指定授权回调页面域名时发现需要下载一个txt文件。也就是说,当我们访问:http://< 指定网页授权域名>/<txt文件名>应正确返回当前txt文件的内容.

示例代码:

0.2.2.0.1. 配置文件: application.yml
wx_official_account:
 appAccount: …
 appID: …
 appSecret: …
 appURL: …
 appToken: …
 appEncodingAESKey: …
 
 MP_verify_code: tfrui9HHYVAMFoXZ
…
…
0.2.2.0.2. Controller层
package com.Controller;

import java.io.PrintWriter;
…
…
import lombok.extern.slf4j.Slf4j;

/**
 * Controller
 * @author ShawnNie
 * 2019-08-16 15:30:11
 * 微信网页授权相关文档: 
 *         https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842#4 (适用于服务号);
 */
@RestController
@Slf4j
@RequestMapping(value="/official_account",produces="application/json;charset=UTF-8")
public class Wechat_officialAccount_Action extends Project_baseAction{

    @Autowired
    private WX_OfficialAccount wX_OfficialAccount;
    @Autowired
    private Environment environment;

    …
     …
    /**
     * @author ShawnNie
     * 2019-09-26 14:02:49
     */
    @ApiOperation(value="获取服务号回调页面授权(回调服务器资源URL专用,非程序调用接口)", notes="获取服务号回调页面授权(回调服务器资源URL专用,非程序调用接口)")
    @RequestMapping(value = "/MP_verify_tfrui9HHYVAMFoXZ.txt",method = RequestMethod.GET)
    public String getMP_verify_code(
    ) {
        return environment.getProperty("wx_official_account.MP_verify_code");
    }
}
0.2.2.0.3. Feign-Interface
package com.feign.client.interf;

import org.springframework.cloud.openfeign.FeignClient;
…
…
import com.feign.hystrix.WXOfficialAccount_module_interfHystrix;

@FeignClient(value="MICROSERVICE-WXOFFICIALACCOUNT",fallback = WXOfficialAccount_module_interfHystrix.class)
public interface WXOfficialAccount_module_interf {
    …
    …
    @RequestMapping(value = "/official_account/MP_verify_tfrui9HHYVAMFoXZ.txt",method = RequestMethod.GET)
    public String getMP_verify_code();
}
0.2.2.0.4. Controller层
package com.Controller;

import java.io.IOException;
…
…
import io.swagger.annotations.ApiParam;

@RestController
public class Admin_Action {

    @Autowired
    private Environment environment;
    @Autowired
    private WXOfficialAccount_module_interf wXOfficialAccount_module_interf;

    ….
     …
    /**
     * @author ShawnNie
     * 2019-09-26 14:02:49
     */
    @ApiOperation(value="获取服务号回调页面授权(回调服务器资源URL专用,非程序调用接口)", notes="获取服务号回调页面授权(回调服务器资源URL专用,非程序调用接口)")
    @RequestMapping(value = "/MP_verify_tfrui9HHYVAMFoXZ.txt",method = RequestMethod.GET)
    public String getMP_verify_code(
    ) {
        return wXOfficialAccount_module_interf.getMP_verify_code();
    }
}

具体配置方法将在章节【常用关键接口解析与应用详细】展开。

0.2.3. 服务器配置: 服务器地址(URL)、令牌(Token)和消息加解密密钥(EncodingAESKey)

  • URL是开发者用来接收微信消息和事件的接口URL地址,用于接收微信服务器发送的数据。微信后台服务推送消息会转发到这个地址上。这里需注意,这个url仅支持http:80端口/ https:443端口,且必须是一个域名,不能是ip地址的形式。
  • Token由开发者任意填写,用作生成签名(该Token会配置在服务器中和接口URL中包含的Token进行比对,从而验证安全性)。
  • EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。

这里需要后台设置一个上述url地址的Controller,以及验证上述token和EncodingAESKey的相关逻辑代码。相关后台服务编写好之后,才能配置成功。此外,提交成功之后,点击“启用配置”,相应的配置才会生效。
具体官方配置标准可参见微信公众平台官方说明文档: https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html

这里附上一段示例代码 ,以供参考(语言: java):

0.2.3.0.1. 配置文件:application.yml
wx_official_account:
 appAccount: …
 appID: …
 appSecret: …
 appURL: https://<service_host>/official_account/token_verify
 appToken: …
 appEncodingAESKey: …
0.2.3.0.2. 配置类
package com.model;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;

@Component
@Scope("singleton")
@Configuration
public class WX_OfficialAccount{
    @Getter@Setter
    @Value("${wx_official_account.appAccount}")
    private static String appAccount;
    @Getter@Setter
    @Value("${wx_official_account.appID}")
    public String appID;
    @Getter@Setter
    @Value("${wx_official_account.appSecret}")
    public String appSecret;
    @Getter@Setter
    @Value("${wx_official_account.appURL}")
    public String appURL;
    @Getter@Setter
    @Value("${wx_official_account.appToken}")
    public String appToken;
    @Getter@Setter
    @Value("${wx_official_account.appEncodingAESKey}")
    public String appEncodingAESKey;
}
0.2.3.0.3. 基础工具类
package com.util;

import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
import java.util.Arrays;

/**
 * ClassName: SignUtil
 * @Description: 请求校验工具类 
 * @author dapengniao
 * @date 2016 年 3 月 4 日 下午 6:25:41
 */
public class SignUtil {
/** 
 * 验证签名 
 * @param signature 
 * @param timestamp 
 * @param nonce 
 * @return 
 */  
public static boolean checkSignature(String token,String signature, String timestamp, String nonce) {  
    String[] arr = new String[] { token, timestamp, nonce };  
// 将 token、timestamp、nonce 三个参数进行字典序排序   
Arrays.sort(arr);  
StringBuilder content = new StringBuilder();  
for (int i = 0; i < arr.length; i++) {  
content.append(arr[i]);  
}  
MessageDigest md = null;  
String tmpStr = null;  

try {  
md = MessageDigest.getInstance("SHA-1");  
// 将三个参数字符串拼接成一个字符串进行 sha1 加密   
byte[] digest = md.digest(content.toString().getBytes());  
tmpStr = byteToStr(digest);  
} catch (NoSuchAlgorithmException e) {  
e.printStackTrace();  
}  

content = null;  
// 将 sha1 加密后的字符串可与 signature 对比,标识该请求来源于微信   
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;  
}  

/** 
 * 将字节数组转换为十六进制字符串 
 * @param byteArray 
 * @return 
 */  
private static String byteToStr(byte[] byteArray) {  
String strDigest = "";  
for (int i = 0; i < byteArray.length; i++) {  
strDigest += byteToHexStr(byteArray[i]);  
}  
return strDigest;  
}  

/** 
 * 将字节转换为十六进制字符串 
 * @param mByte 
 * @return 
 */  
private static String byteToHexStr(byte mByte) {  
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };  
char[] tempArr = new char[2];  
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];  
tempArr[1] = Digit[mByte & 0X0F];  
String s = new String(tempArr);  
return s;  
}  
}
0.2.3.0.4. Controller层代码
package com.Controller;

import java.io.PrintWriter;
…
…
import lombok.extern.slf4j.Slf4j;

/**
 * Controller
 * @author ShawnNie
 * 2019-08-16 15:30:11
 * 微信网页授权相关文档: 
 *         https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842#4 (适用于服务号);
 */
@RestController
@Slf4j
@RequestMapping(value="/official_account",produces="application/json;charset=UTF-8")
public class Wechat_officialAccount_Action extends Project_baseAction{
    
    @Autowired
    private WX_OfficialAccount wX_OfficialAccount;
    @Autowired
    private Environment environment;
    …
…

    /**
     * @author ShawnNie
     * 2019-08-19 19:35:14
     */
    @ApiOperation(value="token验证(回调服务器资源URL专用,非程序调用接口)", notes="token验证(回调服务器资源URL专用,非程序调用接口)")
    @RequestMapping(value = "/token_verify",method = RequestMethod.GET)
    @ApiImplicitParams({
        @ApiImplicitParam(name = "signature", value = "signature", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "timestamp", value = "timestamp", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "nonce", value = "nonce", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "echostr", value = "echostr", required = true, dataType = "String", paramType = "query")
    })
    public void token_verify(
        HttpServletRequest request,
HttpServletResponse response,
        @ApiParam(name="signature",type="String")String signature,
        @ApiParam(name="timestamp",type="String")String timestamp,
        @ApiParam(name="nonce",type="String")String nonce,
        @ApiParam(name="echostr",type="String")String echostr
    ) {
        try {
if (SignUtil.checkSignature(wX_OfficialAccount.appToken,signature, timestamp, nonce)) {
PrintWriter out = response.getWriter();
out.print(echostr);
out.close();
} else {
log.info("这里存在非法请求!");
}
} catch (Exception e) {
log.error(e.toString(), e);
}
    }
…
…
}

0.2.4. 接口权限配置

微信公众平台接口权限信息详见:https://mp.weixin.qq.com/advanced/advanced?action=table&token=1278828167&lang=zh_CN 。在这里可以看到微信服务号、订阅号的全部可用接口信息。

0.3. 常用关键接口解析与应用

微信公众平台的完整版本开发文档可参见官方文档地址: https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
这里本文将开发常用的一些接口的应用逐一解析。

0.3.1. 项目入口及网页授权域名(redirect_uri)的配置

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),引导关注者打开如下请求授权页面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=<APPID>&redirect_uri=<REDIRECT_URI>&response_type=code&scope=<SCOPE>&state=<STATE>#wechat_redirect

这个url需要发到微信应用环境中,使用微信内置的浏览器才能打开。若提示“该链接无法访问”,请检查参数是否填写错误,或是否拥有scope参数对应的授权作用域权限。
参数说明:

参数 必要参数 说明
APPID 公众号的唯一标识
redirect_uri 授权后重定向的回调链接地址。这里需注意,redirect_uri不需要填写http://或https://前缀,只要域名即可。
response_type 直接填写为:code
scope 应用授权作用域,包含两种:snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid);snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节,该值会被微信原样返回,我们可以将其进行比对,防止他人的攻击。
#wechat_redirect 直接在微信打开链接,可以不填此参数。做页面302重定向时候,必须带此参数

应用授权作用域:由于snsapi_base只能获取到openid,意义不大,所以我们的STATE参数通常使用snsapi_userinfo

点开如上链接,点击确认登录即可跳转到服务号配置的回调页面,并获取微信传回的code参数,用于后续的操作。
授权页面如下:

用户确认授权后,即跳转到我们前面配置的redirect_uri所指的地址:

示例代码:

0.3.1.0.1. 配置文件:application.yml
wx_official_account: 
 appID: wx0fd48b6b2847d9a2
 appRedirectURI: botdaddy.emotibot.com/botReindeer
 #welcomePage_url: 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx0fd48b6b2847d9a2&redirect_uri=https%3A%2F%2Fbotdaddy.emotibot.com%2FbotReindeer&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect'
 … 
…
0.3.1.0.2. Controller层
package com.Controller;

import java.io.IOException;
…
…
import io.swagger.annotations.ApiParam;

@RestController
public class Admin_Action {
    
    @Autowired
    private Environment environment;
    @Autowired
    private WXOfficialAccount_module_interf wXOfficialAccount_module_interf;
    
    /**
     * @author ShawnNie
     * 2019-08-19 19:35:14
     */
    @ApiOperation(value="首页(获取服务号H5应用-获取redirect_uri:code参数)(回调服务器资源URL专用,非程序调用接口)", notes="首页(获取服务号H5应用-获取redirect_uri:code参数)(回调服务器资源URL专用,非程序调用接口)")
    @RequestMapping(value = "/",method = RequestMethod.GET)
    @ApiImplicitParams({
        @ApiImplicitParam(name = "code", value = "code参数", required = true, dataType = "String", paramType = "query")
    })
    public RestTemplate<String> get_wxOfficialAccount_application_redirect_code(
        HttpServletResponse response,
        @ApiParam(name="code",type="String")String code
    ) {
        if(code!=null&&!code.isEmpty()) {
            try {
                response.sendRedirect(environment.getProperty("spring.application.redirect_page_url")+("?code="+code));
                return null;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                RestTemplate<String> respEntity=RestTemplate.generate(null, "0000", "ok");
                respEntity.setData(code);
                return respEntity;
            }
        }else {
            return RestTemplate.generate(null, "0001", "参数出错,请稍后重试");
        }
    }
    …
…
}

0.3.2. 通过code参数获取access_token

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#1
使用code换取access_token的请求构造方式:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=<APPID>&secret=<SECRET>&code=<CODE>&grant_type=authorization_code

如请求正确将返回如下格式结果:

{ 
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
 }

参数说明:

参数 必要参数 说明
APPID 公众号的唯一标识
secret 公众号的appsecret
code 第一步获取的code参数
grant_type 填写为: ”authorization_code”

【注意】:

  1. code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
  2. access_token作为换取用户信息的票据,有效期为2个小时,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。

这里贴一段示例代码,以供参考:

0.3.2.0.1. Controller层
package com.Controller;

import java.io.PrintWriter;
…
…
import lombok.extern.slf4j.Slf4j;

/**
 * Controller
 * @author ShawnNie
 * 2019-08-16 15:30:11
 * 微信网页授权相关文档: 
 *         https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842#4 (适用于服务号);
 */
@RestController
@Slf4j
@RequestMapping(value="/official_account",produces="application/json;charset=UTF-8")
public class Wechat_officialAccount_Action extends Project_baseAction{
    
    @Autowired
    private WX_OfficialAccount wX_OfficialAccount;
    @Autowired
    private Environment environment;
    
    /**
     * @author ShawnNie
     * 2019-08-19 19:35:14
     */
    @ApiOperation(value="通过code获取网页accessToken(仅适用于微信服务号)", notes="通过code获取网页accessToken(仅适用于微信服务号)")
    @RequestMapping(value = "/get_accessToken_by_code",method = {RequestMethod.POST})
    @ApiImplicitParams({
        @ApiImplicitParam(name = "code", value = "code参数", required = true, dataType = "String", paramType = "query")
    })
    public String get_accessToken_by_code(
        @ApiParam(name="code",type="String")String code
    ) {
        String request_urlStr="https://api.weixin.qq.com/sns/oauth2/access_token";
        request_urlStr=request_urlStr.concat("?appid="+wX_OfficialAccount.appID);
        request_urlStr=request_urlStr.concat("&secret="+wX_OfficialAccount.appSecret);
        request_urlStr=request_urlStr.concat("&code="+code);
        request_urlStr=request_urlStr.concat("&grant_type="+"authorization_code");
        return URLRequest_Adapter.do_request_URL(request_urlStr, "GET", "{}");
    }
    …
…
}

0.3.3. 根据openid获取用户信息

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#3

请求构造方式:

https://api.weixin.qq.com/sns/userinfo?access_token=<ACCESS_TOKEN>&openid=<OPENID>&lang=<LANG>

如请求正确将返回如下格式结果:

{   
   "openid":" OPENID",
   "nickname": "NICKNAME",
   "sex":"1",
   "province":"PROVINCE",
   "city":"CITY",
   "country":"COUNTRY",
   "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
   "privilege":[ "PRIVILEGE1" "PRIVILEGE2"  ],
   "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

参数说明:

参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
openid 用户的唯一标识
lang 信息返回所用国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语

示例代码:

package com.Controller;

import java.io.PrintWriter;
…
…
import lombok.extern.slf4j.Slf4j;

/**
 * Controller
 * @author ShawnNie
 * 2019-08-16 15:30:11
 * 微信网页授权相关文档: 
 *         https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842#4 (适用于服务号);
 */
@RestController
@Slf4j
@RequestMapping(value="/official_account",produces="application/json;charset=UTF-8")
public class Wechat_officialAccount_Action extends Project_baseAction{
    
    @Autowired
    private WX_OfficialAccount wX_OfficialAccount;
    @Autowired
    private Environment environment;
    
    …
…
    /**
     * @author ShawnNie
     * 2019-09-03 17:55:25
     */
    @ApiOperation(value="根据openid拉取用户信息(仅适用于微信服务号)", notes="根据openid拉取用户信息(仅适用于微信服务号)")
    @RequestMapping(value = "/get_wxuser_info_byOpenid",method = RequestMethod.POST)
    @ApiImplicitParams({
        @ApiImplicitParam(name = "access_token", value = "网页授权接口调用凭证", required = true, dataType = "String", paramType = "form"),
        @ApiImplicitParam(name = "openid", value = "wx-openid:用户的唯一标识", required = true, dataType = "String", paramType = "form"),
        @ApiImplicitParam(name = "lang", value = "返回国家地区语言版本: zh_CN-简体;zh_TW-繁体;en-英语", required = true, dataType = "String",example= "en",defaultValue="zh_CN",paramType = "form")
    })
    public String get_wxuser_info_byOpenid(
        @ApiParam(name="access_token",type="String")String access_token,
        @ApiParam(name="openid",type="String")String openid,
        @ApiParam(name="lang",type="String")String lang
    ) {
        String request_urlStr="https://api.weixin.qq.com/sns/userinfo";
        request_urlStr=request_urlStr.concat("?access_token="+access_token);
        request_urlStr=request_urlStr.concat("&openid="+openid);
        request_urlStr=request_urlStr.concat("&lang="+lang);
        return URLRequest_Adapter.do_request_URL(request_urlStr, "GET", "{}");
    }
    …
…
}

0.4. 微信公众平台开发常用辅助工具简介

0.4.1. Web开发者工具

web 开发者工具是一个桌面应用,通过模拟微信客户端的表现,使得开发者可以使用这个工具方便地在 PC 或者 Mac 上进行开发和调试工作。

web 开发者工具是一个桌面应用,通过模拟微信客户端的表现,使得开发者可以使用这个工具方便地在 PC 或者 Mac 上进行开发和调试工作。
使用web开发者工具,可以帮助开发者如下事项:

  1. 使用自己的微信号来调试微信网页授权;
  2. 调试、检验页面的 JS-SDK 相关功能与权限,模拟大部分 SDK 的输入和输出;
  3. 使用基于 weinre 的移动调试功能;
  4. 利用集成的 Chrome DevTools 协助开发。

为保证开发者身份信息的安全,对于希望调试的公众号,我们要求开发者微信号与之建立绑定关系。具体操作为:公众号登录管理后台,启用开发者中心,在开发者工具——web 开发者工具页面,向开发者微信号发送绑定邀请。绑定页面如下图所示:

开发者在手机微信上接受邀请,即可完成绑定。每个公众号最多可同时绑定10个开发者微信号。邀请确认页面如下图所示:

完成登录和绑定后,开发者就可以开始调试微信网页授权了,注意只能调试自己绑定过的公众号,在微信 web 开发者工具中打开类似的授权页 URL,webview 模拟器显示效果如图:

微信 web 开发者工具集成了 Chrome DevTools。同之前在 PC 上的调试体验一致,因此可以为开发及测试工作提供更直观的状态展示:

0.4.2. 公众平台测试账号

微信公众平台提供了测试账号,在公众账号没有审核之前,也是可以进行开发的。进入后台->开发者工具->公众平台测试账号->进入或直接访问测试账号申请地址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 即可申请。进入网址后,系统会为申请者会分配一个appID和appsecret账号。随后按照上述配置项逐一配置URL、Token等属性,使用相关api即可:

测试号除了不能用微信支付接口,其他接口基本都可以用获取并且可以使用。

待公众号申请通过,即可直接移植项目代码至服务号正式配置,完成最终版本的程序开发。