惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
SecWiki News
SecWiki News
P
Proofpoint News Feed
P
Palo Alto Networks Blog
L
LINUX DO - 热门话题
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Spread Privacy
Spread Privacy
A
Arctic Wolf
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园_首页
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
DataBreaches.Net
量子位
K
Kaspersky official blog
I
InfoQ
W
WeLiveSecurity
Engineering at Meta
Engineering at Meta
Scott Helme
Scott Helme
U
Unit 42
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
T
Troy Hunt's Blog
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
Jina AI
Jina AI
Recent Announcements
Recent Announcements
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
H
Heimdal Security Blog
aimingoo的专栏
aimingoo的专栏
H
Help Net Security
Security Latest
Security Latest
B
Blog RSS Feed
Project Zero
Project Zero
C
Cisco Blogs
S
Securelist
V
Visual Studio Blog
Hugging Face - Blog
Hugging Face - Blog
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
T
Tor Project blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
F
Fortinet All Blogs

Hunsh's Blog

生成个人的 Github PR List 如何选择合适的加密手段 Nginx SNI Proxy 如何优雅导入 k8s.io/kubernetes Make Go mod and Git to use specify .netrc 多架构镜像的体积优化 使用 buildkit 进行多架构构建并提取产物 如何修改镜像 layer(以 sourcemap-less grafana 为例) acme.sh 自动化 Google CA 申请证书 k8s && bazel 项目从 go1.20 升级 go1.21 go serve http and https on same port typecho 迁移到 hexo 实现 hexo 文章和资源在同一目录下 golang mitm 遇到的问题 流式数据专用的 mine-type Golang 正向代理对于 Host 的处理 (RFC 7230) 分享 MacOS 的一些系统fix脚本(dns、sleep) prometheus rate/increase/delta/sum等函数不符合预期或出现小数的原理 [油猴脚本] USTB Everywhere 为校外访问添加访问任意网站的能力
微信小程序嵌入任意公众号文章
2023-12-21 · via Hunsh's Blog

其实是去年做的事情了,现在想起来做一个记录。

背景

小程序可以使用 webview 组件来嵌入 web 内容,对于常规域名需要通过域名所有权认证,对于微信公众号文章需要发布公众号与小程序关联,这在部分情况下是无法实现的(显示非自有公众号文章)。

所以,我们需要一个中间人来帮我们实现这个功能。

实现思路

当然就是实现一个反向代理了,能够反代 mp.weixin.qq.com 的内容。

实现方法

因为需求比较简单,还不至于到写代码的地步,用 nginx 实现就好。

1
2
3
4
5
6
7
8
9
10
11
server
{
server_name mp-proxy.example.com;

# listen block

location /
{
proxy_pass https://mp.weixin.qq.com/;
}
}

然后访问一下就会有靓仔发现,我这个图片怎么显示不出来呢。

通过 network 可以看到图片请求由于 cors 限制导致失败,但是为什么普通的 GET 请求会被 cors 限制呢?

通过 initiator 观察可以看到请求是为了实现懒加载由 script 动态插入的 <img> 标签发出的。那么问题就来了,为什么这个 <img> 需要 cors 检查?

这里就需要一些简单的前端知识,mdn,在跨域条件下,默认 <img> 加载的图片资源会被认为是 tainted 的,除非为 <img> 加上 crossorigin 属性,会在请求中要求 cors 检查,并在浏览器进行 cors 校验。

在公众号文章场景下,并不存在需要 canvas 的场景,所以我们可以将 crossorigin 属性移除,以此来绕开 cors 限制。这里可以通过在 source 中搜索,将所有 crossOrigin 搜索出来,进行替换(主要就是几处 js)。

然后将 html js link 指向 nginx,在 nginx 对 js 内容进行替换,顺便去掉所有的 referrer

注意如果需要替换内容,需要禁止 gzip 等压缩,否则内容无法被替换。

最终实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
server
{
server_name mp-proxy.weshine.club;
include weshine.ssl;

location /s/
{
add_header Referrer-Policy no-referrer;
sub_filter 'origin-when-cross-origin' 'no-referrer';
sub_filter 'strict-origin-when-cross-origin' 'no-referrer';
sub_filter 'crossorigin="anonymous"' '';
sub_filter 'res.wx.qq.com/mmbizappmsg/zh_CN/htmledition/js/assets/weui' mp-proxy.weshine.club/ass/weui;
sub_filter 'res.wx.qq.com/mmbizappmsg/zh_CN/htmledition/js/assets/appmsg.' mp-proxy.weshine.club/ass/appmsg.;
proxy_set_header Accept-Encoding '';
proxy_pass https://mp.weixin.qq.com/s/;
}
location /mp/
{
proxy_pass https://mp.weixin.qq.com/mp/;
}

location /ass
{
sub_filter 's.setAttribute("crossOrigin","Anonymous")' '1';
sub_filter 'e.crossOrigin="anonymous"' '1';
sub_filter 't.crossOrigin="anonymous"' '1';
sub_filter_types 'application/x-javascript';
sub_filter_once off;
proxy_set_header Accept-Encoding '';
proxy_pass https://res.wx.qq.com/mmbizappmsg/zh_CN/htmledition/js/assets;
proxy_buffering on;
proxy_cache mp_proxy;
proxy_cache_valid 200 1d;
}
}

这样就完工了。当然还有部分优化点,比如部分 js 文件过大,可以只留下需要的 js,其他的内容全部 302 出去。这里就不展开了。