一、功能简介
注意:说明:
注意:1. 产品试用说明:未试用过小程序安全防护功能的用户,支持免费领取7-15天体验权益。
注意:2. 接入说明:自动接入仅支持有体验版的标准小程序,无体验版小程序、H5小程序需采用手工接入。
1. 登录 Web 应用防火墙控制台,在左侧导航栏中,选择小程序安全。
2. 在小程序安全防护页面,单击小程序接入切换到小程序接入界面,进行小程序接入或者升级购买。
·若当前 WAF 实例尚未保有小程序安全防护增值能力,可以单击新购申请小程序安全防护增值能力,跳转至购买页按需购买。
·若当前 WAF 实例已保有小程序安全防护增值能力,本页面支持小程序接入以及接入列表管理。
3. 小程序接入支持自动接入和手工接入两种不同的接入方式。
4.小程序接入列表管理。
接入完成后,可以查看小程序卡片在接入防护后的请求次数,以及防护拦截的请求数,了解访问趋势及威胁防护趋势。
二、自动接入
自动接入模式下,配置即时生效,解除即时释放。
注意:自动接入模式不适用于 h5 小程序。
三、步骤1:授权接入
1. 在 小程序安全 > 小程序接入页面,选择自动接入,单击一键接入小程序。
2. 在授权接入页面,单击添加小程序授权。
3. 在新打开的公众平台账号授权页面,使用公众平台绑定的管理员个人微信号扫码完成授权。
注意:说明:
注意:本次授权仅包含开通小程序安全防护能力,不涉及其他权限。
4. 授权完成后,将自动返回授权接入页面。
5. 在授权接入页面,选择需要接入的小程序和接入版本,单击确认接入。
四、步骤2:测试与发布
1. 在测试与发布页面管理小程序源站域名和端口。所有域名接入 WAF 后即可展示体验二维码,供用户扫描验证。
·若域名未全部接入 WAF:不展示体验版二维码,提供前往接入入口,单击后跳转至接入管理界面。具体操作详情请参见 CNAME 接入 和 云原生接入。
·若域名均完成接入 WAF:自动展示体验版二维码。客户扫码进行小程序体验测试,默认将小程序体验版请求接入微信私有链路,完全不影响线上业务流量。
2. 完成二维码验证后,编辑微信网关配置。
配置项说明
·接入版本:选择需要接入 WAF 防护的小程序版本。
·开发版:接入开发者调试上传的开发版本。
·体验版:接入内部测试使用的体验版本。
·线上版本:接入已发布给终端用户的正式版本。
·全部版本:同时接入该小程序的所有版本(推荐)。
·发布模式:控制已接入的安全防护流量如何逐步放量至源站。仅当接入版本为线上版本或全部版本时可用,开发版和体验版直接全量接入。
·全局灰度发布:已接入的全部流量,按照设置的灰度比例进入小程序安全防护网关,由网关转发至服务源站域名。
·灰度配置:0%~100%,表示经过安全防护网关的流量占总流量的百分比。基于微信账号的灰度机制,扩大灰度比例时,系统自动扩展灰度账号范围,已灰度的账号不受影响。
·自定义灰度发布:已接入的部分流量,可按自定义规则(域名 + URI 路径 + 用户组)定向进入安全防护网关,由网关转发至服务源站域名。
·域名:从当前已接入 WAF 保护的域名列表中选择需要灰度的域名。
·URI / PATH:输入需要灰度的 URL 路径,如 /api/v1/*。
·灰度比例:0%~100%,灰度比例仅对线上版本生效,开发版及体验版均为全量接入。灰度比例数值,在实际灰度过程中可能为非精确数值;灰度时,当某一用户命中灰度规则后,后续再次使用业务仍然会被灰度。
·用户组:从线上组、测试组或其他组中选择一组作为灰度对象。可单击用户组管理对用户组进行管理。
·白名单:灰度发布的目标对象(即命中灰度的微信 ID)。
·黑名单:发布例外的微信 ID(即使命中灰度规则也不进入安全防护网关)。
注意:说明:
·高级设置:以下参数需要单击高级设置后方可配置。
·请求包流量标记:开启后,可配置客户端信息透传或自定义 Header 标签传递,用于后续流量识别与分析。
·自定义流量标记:向后端添加固定的 Header 值,用于标记业务来源。例如X-Source: mobile-app。
·自定义 Header 传递:将客户端请求中的某个 Header 原样透传至后端,用于透传客户端信息。例如透传X-Real-IP。
·微信客户端标签传递:透传客户端请求中微信指定前缀的 Header,用于透传微信环境信息。例如x-wx-version、x-wx-platform。
·轻量接入配置:开启后,可指定特定域名访问路径的请求和响应包均不加密传输,以降低网关处理开销。
注意:说明:
·超时时间:设置网关向源站转发请求时的等待超时时长,范围1~59秒。当源站在指定时间内未返回响应时,网关将中断连接并返回超时错误。
·回包 Header 头配置:控制从源站返回的回包中 HTTP Header 键名的大小写格式。
·key 全小写:回包 Header 键名统一转换为小写。
·key 首字母大写:回包 Header 键名的首个字母保持大写,其余字母小写。
·请求头过滤:开启后,可选择需要过滤的请求 Header,这些 Header 不会被转发到源站。
·基础库起始版本:指定需要接入安全防护的小程序基础库最低版本。低于该版本的客户端请求将不被安全防护网关拦截。
·基础库版本分布详情:可查看当前接入小程序的用户基础库版本分布统计,帮助评估各版本的覆盖率,辅助决策「基础库起始版本」的配置。
·失败请求自动重试:开启后,当网关向源站发起请求遇到服务端错误(HTTP 状态码 5xx)时,会自动重新发起一次请求。
·自动降级回源:开启后当网关 QPS 达到动态阈值(根据当前接入流量规模与安全防护策略复杂度,系统自动评估并设定 QPS 阈值)时,超额请求自动回源;流量回落至阈值下后,自动恢复全量网关防护。
·黑名单:单击配置,将微信账号添加进黑名单,列入黑名单的微信账号,其请求将绕过微信网关的防护。
注意:说明:
·黑名单数量:展示当前黑名单中已添加的微信账号数量(当前已配置 0 个)。
·备注:200字符以内。
五、步骤3:确认发布,开启安全防护
1. 在测试与发布页面,单击已完成测试,确定发布,在弹出的确认窗口中单击确定,完成自动接入。
2. 发布后,默认将小程序线上请求接入微信私有链路,受小程序安全防护能力保护。
六、发布管理
自动接入成功后,在 小程序安全 > 小程序接入页面,支持对接入的小程序取消发布,以及修正后重新发布管理能力。
·发布回滚:完成发布后,支持单击小程序卡片中的编辑进入发布管理页面,单击取消发布,经过二次确认后,自动将线上版小程序请求切换至原业务公网链路,不经过小程序安全防护功能。
·重新发布:取消发布后,单击小程序卡片中的编辑或接入线上版,即可唤起发布管理页面,重新发布后,将线上版小程序请求重新接入小程序安全防护功能。
七、手工接入
适用于各种小程序接入,只需简单修改代码、测试并验证发布即可开启小程序安全防护能力。
八、步骤1:接入配置
1. 在 小程序安全 > 小程序接入页面,选择手工接入,单击开始接入。
2. 在新建小程序接入侧边栏中,填写完对应配置内容,即可单击保存配置,进入下一步。
| 参数名称 | | 说明 |
| 节点名称 | | 自定义节点名称。 |
| 小程序 ID | | 小程序唯一 ID,可以扫码登录 微信公众平台获取。 |
| 流量来源 | | 根据实际情况选择流量来源。小程序接入Web SDK 接入APP SDK 接入 |
| 域名 | 域名 | 选择已接入的小程序域名。 |
| | 协议端口 | 选择协议端口。 |
| 高级设置 | 回包 Header 头配置 | key 全小写key 首字母大写 |
| 备注 | | 备注,200个字符以内。 |
九、步骤2:客户端配置
微信开发者工具 中,对小程序项目的代码进行适配。
十、小程序接入
1. 环境加载。
在项目配置文件 app.json 中添加如下配置,以获得更好的兼容性,建议在发布前通过预览或者体验版在真机上测试小程序功能是否正常。
{ "cloud": true, "cloudVersion": "alpha"}
2. 域名配置。
2.1 在客户端配置页面,复制并获取你的网关接入域名。
2.2 前往 微信公众平台,在开发管理中修改服务器域名,将网关的接入域名新增到小程序合法域名列表中。
3. 初始化小程序网关。
·手工接入:测试验证更改自己的网关 ID 信息,下面调用方法不支持一键接入和自动回退能力。
// app.js App({ async onLaunch() { const gateway = wx.cloud.services.Gateway({ // 接入域名:即在网关接入层生成的域名,请复制“域名配置”中网关的接入域名。 domain: 'a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com', }); // 赋值到 cloud 对象上,方便后续调用 wx.cloud.gateway = gateway; } })
·一键接入:测试验证更改自己的网关 ID 信息,下面调用方法通过在app.js中的onLaunch添加如下代码实现劫持wx.request ,模拟实现一键接入和自动回退能力。
// 支持自动降级到 request 的版本,需要注意,降级时请求将不受安全保护 App({ onLaunch() { const wfappBaseInfo = wx.getAppBaseInfo(); const gateway = wx.cloud.services.Gateway({ // 接入域名:即在网关接入层生成的域名,请复制“域名配置”中网关的接入域名。 domain: 'a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com', }); // 赋值到 cloud 对象上,方便后续调用 wx.cloud.gateway = gateway; const __origin_req = wx.request; const gatewayDomainList = [ 'https://jacky250722.testwaf.com' ]; // url 前缀匹配命中 gatewayDomainList 中的访问请求,将使用cloudsdk进行访问 function checkGateway(url) { for (const element of gatewayDomainList) { if (url.startsWith(element)) { return true } } return false } // 重写 wx.request function request(option) { if (checkGateway(option.url)) { if (!option.header) option.header = {} option.header['X-WX-HTTP-MODE'] = "REROUTE" option.header['X-WX-CONF-VERSION'] = "0" return gateway.call({ // 填写完整域名(包括协议头和 host 部分,如 https://api.example.com/path?query=xxx) // 如果 URL 中包含中文,需要手动 encode path: option.url, …option }).then(response => { if (wfappBaseInfo.SDKVersion.startsWith("2.")) { option.success(response) // 如果是 SDK 版本 2.x,调用 option.success } }).catch(err => { console.log("网关请求失败,降级到 request", err) __origin_req(option) }) } return __origin_req(option) } Object.defineProperty(wx, 'request', { value: request, enumerable: true, configurable: true, }) },});
4. 调用网关。
·若 初始化小程序网关 选择手工接入,需要单独调用网关,调用形式除path参数外,与wx.request基本相同。
·若 初始化小程序网关 选择一键接入,可以通过网关调用实现单个域名的特殊处理。
wx.cloud.gateway.call({ // 请填写完整的请求路径(包括协议头和 host 部分,如 https://api.example.com/path?query=xxx),中文需要encodeURIComponent函数转译 path: `https://api.example.com/?word=${encodeURIComponent('微信网关访问')}`, // 请求方法 method: 'GET', // 客户端发起请求时,可以自定义请求头中的header字段,如下: header: { // 'my-header': 'xxxxx' // ! 重要:多域名场景下,需要携带这个 Header,以启用多域名支持能力 'X-WX-HTTP-MODE': 'REROUTE', } // 其余参数与 wx.request 相同}).then(result => { console.log('微信网关访问结果: ', result)})
调用成功示例:
WAF 检测到攻击,拦截示例:
十一、Web SDK 接入
原生接入
1. 环境加载。
在 HTML 中,引入小程序安全防护网关的 Web SDK。
<script src="https://res8.wxqcloud.qq.com.cn/cloud-sdk/v3.0.19/cloud.js" importance="VeryHigh"></script>
2. 域名配置。
2.1 在客户端配置页面,复制并获取你的网关接入域名。
2.2 前往 微信公众平台,在开发管理中修改服务器域名,将网关的接入域名新增到小程序合法域名列表中。
3. 初始化网关对象和实例。
测试验证更改自己的小程序安全防护网关 ID 信息,小程序 appid,网关接入节点域名信息。
const c1 = new cloud.Cloud({ identityless: true, resourceAppid: 'wxcb05cd6fc6f5f8bd', // appid,填入接入的小程序 appid config: { customDomain: 'https://a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com' // 网关接入节点域名,主要需要包括协议头 } }) c1.init() // 初始化实例 const gateway = c1.services.Gateway({ domain: 'a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com' }) // 网关接入节点域名,注意不包含协议头
4. 调用网关。
请求小程序安全防护网关地址,需要加密的请求的方法进行替换。
const gateway = c1.services.Gateway({ domain: 'a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com' }); // 小程序安全防护的接入节点域名,不包含协议头gateway .call({ // 请填写完整的请求路径(包括协议头和 host 部分,如 https://api.example.com/path?query=xxx),中文需要encodeURIComponent函数转译 path: `https://api.example.com/?word=${encodeURIComponent('微信网关访问')}`, // 请求方法 method: 'GET', // 发起请求时,可以自定义请求头中的header字段,如下: header: { // 'my-header': 'xxxxx' // ! 重要:多域名场景下,需要携带这个 Header,以启用多域名支持能力 'X-WX-HTTP-MODE': 'REROUTE', } }) .then(res => { console.log(res); // 网关返回结果 });
Axios 接入
1. 环境加载。
在 HTML 中,引入小程序安全防护网关的 Web SDK。
<script src="https://res8.wxqcloud.qq.com.cn/cloud-sdk/v3.0.19/cloud.js" importance="VeryHigh"></script>
2. 域名配置。
2.1 在客户端配置页面,复制并获取你的网关接入域名。
2.2 前往 微信公众平台,在开发管理中修改服务器域名,将网关的接入域名新增到小程序合法域名列表中。
3. 初始化网关对象和实例。
新建一个 wxadapter.js,文件内容如下,修改其中的 GATEWAY_DOMAIN 字段为接入的网关域名(详见域名配置),以及接入小程序 IDresourceAppid。
import { AxiosHeaders } from 'axios';import settle from 'axios/unsafe/core/settle';import fetchAdapter from 'axios/unsafe/adapters/fetch';import resolveConfig from 'axios/unsafe/helpers/resolveConfig.js';// 网关接入节点域名const GATEWAY_DOMAIN = 'a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com' const c1 = new window.cloud.Cloud({ identityless: true, resourceAppid: 'wxcb05cd6fc6f5f8bd', // appid,填入接入的小程序 appid config: { customDomain: `https://${GATEWAY_DOMAIN}`, },});c1.init(); // 初始化实例const gateway = c1.services.Gateway({ domain: GATEWAY_DOMAIN,}); // 网关接入节点域名,不包含协议头const wxadapter = (config) => new Promise((resolve, reject) => { let { url, …resolved } = resolveConfig(config) gateway .call({ …resolved, path: url, // 完整的请求地址,包含协议、域名和路径,例如:https://api.example.com/v1/chat/completions header: { 'X-WX-HTTP-MODE': 'REROUTE', …config.headers, }, }) .then((result) => { const headers = new AxiosHeaders(result.header); const response = { config, data: result.data, headers, status: result.statusCode, statusText: result.errMsg ?? 'OK', cookies: result.cookies, }; settle(resolve, reject, response); }) .catch( // 降级为普通 fetch 请求 (error) => { console.log( error, 'error when using wx gateway, using fetch adapter to fallback' ); return fetchAdapter(config).then((result) => { const response = result; settle(resolve, reject, response); }).catch(reject); } ); });export default wxadapter;
4. 引入 adapter。
在应用入口 js 处引入上面的 adapter。
import axios from 'axios';import wxadapter from './wxadapter';// 应用到默认的 axios 实例axios.defaults.adapter = wxadapter;const fallback = false; // 配置是否降级 false 为不降级,失败走降级重试链路,true 为默认降级// 也可以使用独立的 axios 实例if (!fallback) { axios.create({ // …config adapter: wxadapter, });} else { axios.create({ // …config });}
5. 测试请求。
测试请求是否正常,以及请求是否通过加密即可。
注意:说明:
注意:2.0.4 的 SDK 不允许打开 DevTools 调试工具,否则将被拦截。
十二、APP SDK 接入
IOS 系统 SDK 接入
1. 获取 SDK 和网关域名。
·SDK:前往客户端配置页面,下载 SDK iOS 资源包。SDK 包含:WXCloud.h(头文件),libWXCloudCore.a(静态库),WXCloudSample(示例工程)。
·网关域名:你的接入域名即为网关域名。
2. 添加头文件、静态库和依赖。
导入示例工程,添加头文件、静态库,添加底层依赖系统动态库 libz。
3. 调用网关。
其中,key,secret 为通过 工单 申请具体获得当前接入小程序的专属值,sGwDomain 为步骤 1 中获取的网关域名。
#import "WXCloud.h"// 初始化网关(key, secret)std::string sAppKey = "";std::string sAppSecret = "";std::string sGwDomain = "a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com";wxcloud::WXCloud &oInstance = wxcloud::WXCloud::getSharedInstance(sAppKey, sAppSecret, sGwDomain);// 调用wxcloud::RequestType requestType = wxcloud::RequestType::SYNC; // 同步请求wxcloud::HttpMethod httpMethod = wxcloud::HttpMethod::POST; // http methodstd::string sPath = "/6ea7d45b-ec80-4cb3-b2a5-f7bed1b48e7a"; // http path,不带业务域名wxcloud::header_type mapHeaders; // http headermapHeaders["HOST"] = "webhook.site"; // 业务域名mapHeaders["x-wx-route-tag"] = "6cb24a7e69a3f58147741a736be69e0b"; // 业务域名md5std::string sBody = "hello world."; // http bodyoInstance.callContainer(requestType, httpMethod, sPath, mapHeaders, sBody, [](long ret, long http_code, std::map<std::string, std::string>headers, std::string body){ // 先判断ret: 0 成功,非0失败;再判断http_code // ret == 0 && http_code == 200 表示调用成功 if(ret == 0 && http_code == 200) { } else { // ret = [1-98] 详见 https://curl.se/libcurl/c/libcurl-errors.html }});
Android 接入
1. 获取 SDK。
前往客户端配置页面,下载 SDK Android 资源包。SDK 包含:libWXCloudCore.so(动态库:arm64-v8a 和 armeabi-v7a 两种架构),WXCloudCore.java、WXCloudContainerResp.java(JNI 类),WXCloudDemo(示例工程)。
2. 域名配置。
2.1 在客户端配置页面,复制并获取你的网关接入域名。
2.2 前往 微信公众平台,在开发管理中修改服务器域名,将网关的接入域名新增到小程序合法域名列表中。
3. 添加头文件、静态库和依赖。
SDK 底层依赖系统动态库 -lz -llog。
3.1 导入示例工程,添加libWXCloudCore.so,并在build.gradle 指定动态库目录 libz。
android { … sourceSets{ main{ jniLibs.srcDirs = ['libs'] } } …}
3.2 新建 com.tencent.wxcloud 包,并添加 WXCloudCore.java 和 WXCloudContainerResp.java。
4. 调用网关。
其中,key,secret 为通过 工单 申请具体获得当前接入小程序的专属值,sGwDomain 为步骤 2 中的配置的网关域名。
// 初始化网关(key,secret,网关域名)String sAppKey = "";String sAppSecret = "";String sGwDomain = "a1dxxxx4a-wxxxxx1259xxxx5086.sh.wxgateway.com";this.wxCloudCore = new WXCloudCore(sAppKey, sAppSecret, sGwDomain);// 调用String sRequestType = "SYNC"; // 同步请求String sHttpMethod = "POST"; // http methodString path = "/6ea7d45b-ec80-4cb3-b2a5-f7bed1b48e7a"; // http path,不带业务域名HashMap<String, String> header = new HashMap<>(); // http headerheader.put("HOST", "webhook.site"); // 业务域名header.put("x-wx-route-tag", "6cb24a7e69a3f58147741a736be69e0b"); // 业务域名md5String sBody = "hello world."; // http bodybyte [] arrBody = sBody.getBytes(); // 二进制WXCloudContainerResp oResp = this.wxCloudCore.callContainer(sRequestType, sHttpMethod, path, header, arrBody);System.out.printf("wxcloud resp.ret=%d, resp.http_code=%d, resp.body=%s, resp.headers=%s", oResp.respRet, oResp.respHttpCode, String.valueOf(oResp.respBody), oResp.respHeaders);
十三、步骤3:测试验证与发布确认
1. 小程序客户端代码适配完成之后,按照小程序发布标准,进行测试及发布。
2. 小程序新版本正式发布之后,在 小程序安全 > 小程序接入页面的接入配置第三步中同步修改状态为流量接入安全网关已验证,已发布,单击完成,即整个接入过程完成。