微信5发布之后,产品那边反映一键关注的方法不管用了。

所谓的一键关注,之前就是使用一个URL地址,写个A标签,类似下面这样:

1
<a href='weixin://qr/tnXb1AvEJDVbhxq3nyCS'>关注曝工资</a>

或者用http的也行:

1
<a href='http://weixin.qq.com/r/tnXb1AvEJDVbhxq3nyCS'>关注曝工资</a>

当用户在非微信浏览器上点击这个链接时,假如用户设备上安装了微信,微信就会拦截这两种请求,打开并跳转到该公众账号的介绍页面(当然没登陆的会先提示登录)。

微信5发布之后,产品那边就发现,假如点击一键关注,浏览器不会跳转到微信的介绍页面,甚至还会提示错误并退出。

为了确定微信5做了什么限制,于是我用apktool分别对微信4.5和5.0的版本解压出来对比了下,才确定了原因。

这是微信5.0的manifest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<activity android:theme="@style/Theme.Transparent" android:name="com.tencent.mm.ui.qrcode.GetQRCodeInfoUI" android:permission="com.tencent.mm.permission.GET_QRCODE_INFO" android:exported="false" android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="weixin.qq.com" android:pathPrefix="/r/" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="weixin" android:host="qr" />
</intent-filter>
</activity>

这是微信4.5的manifest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<activity android:theme="@style/Theme.Transparent" android:name=".ui.qrcode.GetQRCodeInfoUI" android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="weixin.qq.com" android:pathPrefix="/r/" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="weixin" android:host="qr" />
</intent-filter>
</activity>

可以发现,微信5增加了一个叫做GET_QRCODE_INFO的自定义权限,猜测是为了当扫描二维码的时候,依然可以通过跳转网址跳转到关注页面。再来看看这个权限的定义声明:

1
2
<permission android:name="com.tencent.mm.permission.GET_QRCODE_INFO" android:protectionLevel="signature" />
<uses-permission android:name="com.tencent.mm.permission.GET_QRCODE_INFO" />

注意到protectionLevel=signature,要求app的签名跟微信的签名一致,才能有这个权限。微信的私钥可能拿到吗?当然基本上不可能,所以只有微信的”扫一扫”,才可以跳转到相应的介绍页,第三方应用都可以洗洗睡了。

理论上可以暴力地使自己的应用成为系统应用,这样就可以无视微信的限制,只是这个方法并不现实……