Android浅谈网页打开APP(二)

上一节粗略讲述了URL Scheme如何打开app,这一节对这一机制进行详细说明

Android安全开发之浅谈网页打开App(一)

一. 网页打开APP简介

Android有一个特性,可以通过点击网页内的某个链接打开APP,或者在其他APP中通过点击某个链接打开另外一个APP,一些用户量比较大的APP,已经通过发布其AppLink SDK,开发者需要申请相应的资格,配置相关内容才能使用。这些都是通过用户自定义的URI scheme实现的,不过背后还是Android的Intent机制。Google的官方文档《Android Intents with Chrome》一文,介绍了在Android Chrome浏览器中网页打开APP的两种方法,一种是用户自定义的URI scheme(Custom URI scheme),另一种是“intent:”语法(Intent-based URI)。

第一种用户自定义的URI scheme形式如下:

scheme://host/path?parameters

第二种的Intent-based URI的语法形式如下:

intent://host/uri_path#Intent;参数;end

因为第二种形式大体是第一种形式的特例,所以很多文章又将第二种形式叫Intent Scheme URL,但是在Google的官方文档并没有这样的说法。

注意:使用Custom URI scheme给APP传递数据,只能使用相关参数来传递数据,不能想当然的使用scheme://host/uri_path#intent;参数;end的形式来构造传给APP的intent数据。具体原因看本文3.1章节

此外,还必须在APP的Androidmanifest文件中配置相关的选项才能产生网页打开APP的效果,具体在下面讲。

二. Custom Scheme URI打开APP

2.1 基本用法
需求:使用网页打开一个APP,并通过URL的参数给APP传递一些数据。
如自定义的Scheme为:

wdgz://wdfull/card?card_id=828

网页端的写法如下:

<?xml version="1.0 encoding="utf-8?>
<html>
     <head>
          <title>URL打开App</title>
     </head>
     <body>
          <a href="wdgz://wdfull/card?card_id=828">打开豌豆公主App</a>
     </body>
</html>

APP端接收来自网页信息的Activity,要在Androidmanifest.xml文件中Activity的intent-filter中声明相应action、category和data的scheme等。

<activity android:name="MyActivity">
            <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="wdgz"
                    android:host="wdfull" />

            </intent-filter>
</activity>

在MyActivity中接收intent并且获取相应参数的代码:

 @Override
 protected void onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val intent = getIntent()
        Log.d("shixiangyu",intent.toURI())
        val uri = intent.getData()

此时,我们可以看一下打印的intent.toURI()信息:


image.png

由上图可知Android系统自动为Custom URI scheme添加了默认的 #intent字段,以及category,launchFlags,component等信息。

另外还有以下几个API来获取相关信息:

getIntent().getScheme(); //获得Scheme名称

getIntent().getDataString(); //获得Uri全部路径

getIntent().getHost(); //获得host

三. Intent-based URI打开APP

3.1基本用法
Intent-based URI语法:

intent://
host/uri_path
#Intent;
action=[action];
category=[category];
component=[component]
scheme=[scheme];
end

注意:第二个Intent的第一个字母一定要大写,不然不会成功调用APP。

如何正确快速的构造网页端的intent?

可以先建个Android demo app,按正常的方法构造自己想打开某个组件的Intent对象,然后使用Intent的toUri()方法,会得到Intent对象的Uri字符串表示,并且已经用UTF-8和Uri编码好,直接复制放到网页端即可。

               Intent i = new Intent();
               i.setAction("android.intent.action.VIEW");
               i.addCategory("android.intent.category.BROWSABLE");
               i.addCategory("android.intent.category.DEFAULT");
               i.setData(Uri.parse("wdgz://wdfull/card?card_id=828"));

               Log.d("shixiangyu",i.toUri(Intent.URI_INTENT_SCHEME));

结果:


image.png

如果在demo中的Intent对象不能传递给目标APP的Activity或其他组件,则其Uri形式放在网页端也不可能打开APP的,这样写个demo容易排查错误。

另外,对于传递的参数的设置,可以直接跟在uri_path里面,然后直接通过intent.setData()的形式进行传递,上面的就是此种形式,也可以通过intent.putExtra()的方式进行传递,如

               Intent i = new Intent();
               i.setAction("android.intent.action.VIEW");
               i.addCategory("android.intent.category.BROWSABLE");
               i.addCategory("android.intent.category.DEFAULT");
               i.setData(Uri.parse("wdgz://wdfull/card"));
               i.putExtra("card_id","828");
               Log.d("shixiangyu",i.toUri(Intent.URI_INTENT_SCHEME));

我们来看一下此时构造的intent长相如何:


image.png

S.card_id跟的就是intent对象的putExtra()方法中的数据。采取这种方式的话,从intent中获取相关信息就有通过intent,getStringExtra()方法了。

APP端中的Androidmanifest.xml的声明写法同2.1节中的APP端写法完全一样。

然后服务端的代码便可换成:

<a href="intent://wdfull/card?cart_id=828#Intent;scheme=wdgz;category=android.intent.category.DEFAULT;category=android.intent.category.BROWSABLE;end">
打开豌豆公主App
</a>

接着,我们在被打开的MyActivity中打印intent.toUri()信息:

image.png

不要惊呼,没有看错,android系统自动把intent://替换成了wdgz://,另外在后面添加了 component 的相关信息。

问题来了,为何不能用scheme://host#intent;参数;end的形式来构造传给APP的intent数据,然后直接给网页端呢?

如对于:

<a href="wdgz://wdfull/card?cart_id=828#Intent;scheme=wdgz;category=android.intent.category.DEFAULT;category=android.intent.category.BROWSABLE;end">打开豌豆公主App</a>

是的,就是因为Android系统会自动为Custom URI scheme而非Intent-based URI添加默认的#intent等信息。

四. 风险评估

常见的用法是在APP获取到来自网页的数据后,重新生成一个intent,然后发送给别的组件使用这些数据。比如使用Webview相关的Activity来加载一个来自网页的url,如果此url来自url scheme中的参数,如:wdgz://wdfull/html?load_url=http://m.wamdougongzhu.cn

如果在APP中,没有检查获取到的load_url的值,攻击者可以构造钓鱼网站,诱导用户点击加载,就可以盗取用户信息。

在Webview加载load_url时,结合APP的自身业务采用白名单机制过滤网页端传过来的数据,黑名单容易被绕过。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 155,541评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 65,987评论 1 285
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,387评论 0 236
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,325评论 0 201
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,657评论 3 284
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,125评论 1 202
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,519评论 2 305
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,242评论 0 193
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,863评论 1 234
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,198评论 2 239
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,747评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,106评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,635评论 3 227
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,926评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,631评论 0 190
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,131评论 2 261
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,083评论 2 257

推荐阅读更多精彩内容