分享篇 - Android 如何使用其他 APP 的 App ID 做微信分享

1. 需求背景

一些 APP 分享到微信,朋友圈经常被封。如果在微信分享时,我们将微信分享的 App ID 改成其他应用的 App ID,就可以使用其他 App 的名义进行分享,而且分享出去的内容,显示的发送方都不会受影响。

 

2. 实现原理

微信对第三方的调用有着严格的验证:App ID,包名,及应用签名,只有这三个和申请的都完全匹配,才能调用分享。那么如何突破这三个校验点呢?

 

2.1 App ID

在点击微信分享时,会构建一个 IWXAPI 对象,用于执行微信分享的一系列操作。这个对象的构造器接收两个参数:context 上下文对象和 App ID。第一个校验点解决方案很简单,直接通过下发的配置动态设置 App ID 即可。

 

2.2 包名

微信分享时,会校验包名,如果包名与申请 App ID 时填写的包名不同,微信会给出包名不一致的错误提示。如何绕过这一点呢?简单看一下微信 SDK 的实现, 微信 SDK 经过层层调用,最后会调用到以下代码:

public static boolean send(Context var0, MMessageActV2.Args var1) {
        if (var0 != null && var1 != null) {
            if (d.i(var1.targetPkgName)) {
                Log.e("MicroMsg.SDK.MMessageAct", "send fail, invalid targetPkgName, targetPkgName = " + var1.targetPkgName);
                return false;
            } else {
                if (d.i(var1.targetClassName)) {
                    var1.targetClassName = var1.targetPkgName + ".wxapi.WXEntryActivity";
                }

                Log.d("MicroMsg.SDK.MMessageAct", "send, targetPkgName = " + var1.targetPkgName + ", targetClassName = " + var1.targetClassName);
                Intent var2;
                (var2 = new Intent()).setClassName(var1.targetPkgName, var1.targetClassName);
                if (var1.bundle != null) {
                    var2.putExtras(var1.bundle);
                }

                String var3 = var0.getPackageName();
                var2.putExtra("_mmessage_sdkVersion", 621019136);
                var2.putExtra("_mmessage_appPackage", var3);
                var2.putExtra("_mmessage_content", var1.content);
                var2.putExtra("_mmessage_checksum", b.a(var1.content, 621019136, var3));
                var2.putExtra("_message_token", var1.token);
                if (var1.flags == -1) {
                    var2.addFlags(268435456).addFlags(134217728);
                } else {
                    var2.setFlags(var1.flags);
                }

                try {
                    var0.startActivity(var2);
                } catch (Exception var4) {
                    Log.e("MicroMsg.SDK.MMessageAct", "send fail, ex = " + var4.getMessage());
                    return false;
                }

                Log.d("MicroMsg.SDK.MMessageAct", "send mm message, intent=" + var2);
                return true;
            }
        } else {
            Log.e("MicroMsg.SDK.MMessageAct", "send fail, invalid argument");
            return false;
        }
    }

上述代码的逻辑意思是:包装好 SDK 版本号,App 包名,消息内容,App ID 生成的 token,然后将这些数据打包好传递给微信,启动微信界面。

代码中的包名是动态获取的,要做到修改包名,就得回到上面说到的 IWXAPI 的构造器了,它接收两个参数:context 上下文对象和 App ID,微信 SDK 正是用传入的这个 context 来获取应用包名的。解决方案就是:代理这个 context 对象,重新实现它获取包名的方法,返回需要修改的 App ID 对应的包名:

           mApi = WXAPIFactory.createWXAPI(new ContextWrapper(mActivity) {
                @Override
                public String getPackageName() {
                    // TODO 待借壳分享出去的应用包名
                    return "";
                }
            }, wxAppId);

这样微信 SDK 内部获取到的包名就是我们代理类返回的包名了。

 

2.3 应用签名

从最后的逻辑来看,启动微信进行分享时,并没有校验应用签名,在 SDK 的其他地方也没有发现对发起方应用签名的校验。所以微信是在它被启动后, 在它自身的页面做了签名校验处理:

通过拿到的包名,去手机本地查找对应的 App 的签名信息,然后再通过拿到的 token 和包名,去服务器获取应用注册时填写的签名,两个签名进行对比,如果不一致,则会给出错误提示。所以只要你手机本地安装了这个 App ID 对应签名的应用,即可通过校验。

 

3. 优势

  • 实现简单,只需要服务器动态下发其他应用的 App ID 和包名即可,无需获取复杂的签名信息
  • 不会影响其他功能,如微信支付,登陆等,仅在当次调起分享时有效

 

4. 缺陷

  • 通过微信分享到好友列表或朋友圈后,微信会给出一个回到 App ID 对应的 App 的提示,体验不够友好
  • 手机本地必须安装了对应 App ID 的应用,否则微信分享调起失败

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值