【Android】GCM restricted_package_name的作用?

前言

      在做GCM推送的时候,遇到GCM Server返回“Invalid Package Name”的错误信息。一开始以为是服务端的Server API Key与APP没有匹配上,后来查明是后台人员在发往GCM Server的消息中加了restricted_package_name这个字段,并且传了错误的值。于是引发了以下对restricted_package_name字段的探究。

restricted_package_name的含义

官网是这样解释的:

This parameter specifies the package name of the application where the registration tokens must match in order to receive the message.

即是说,只有restricted_package_name字段中指定包名的应用才能接收到推往设备的消息。

restricted_package_name的验证

      于是,我们尝试在推送消息中加入restricted_package_name字段,并赋以不同的value进行测试,得到如下结论:

     * 正确的包名,推送成功。

     * 空字符串,推送成功。

     * 错误的包名,推送失败。返回“Invalid Package Name”错误信息。

      由以上的测试,可以看出:只要restricted_package_name予以有效赋值,GCM Server就会发往指定包名的应用。但是,如果推送的registration ids并不是为该应用分配的,则会报“Invalid Package Name”,信息不会被发送。

restricted_package_name是否必要?

首先我们先来理一下推送流程:

1.在GCM官网创建应用Create or choose an app。我们填写APP packagename,由此生成Server API Key以及APP SenderId。

2.APP通过SenderId,获取registration id(类似iOS的deviceToken),并发给Server。

3.Server通过API Key发送消息到registration id标识的设备上的APP。

      从流程中,可以看到API Key、SenderId、registration id是相互关联的。并且,我们似乎可以猜测,GCM Server收到推送请求时能够判断API Key与registration id是否匹配,并且是发往哪一个应用的。

      为什么说能识别出发往哪一个应用?这主要是出于两个方面:一是创建应用时需要填写packagename,通过API Key可以找出对应的packagename;二是registration id,官网写着“a token that can identify and authorize the instance of the application on the device.This is similar to an OAuth2 token except, it applies to the application instance instead of a user.”即它至少包含device和application两个信息,同样可以拿到packagename;而且从上文“Invalid Package Name”的错误信息也能说明registration id可以获取packagename。

      写到这里,估计大家都困惑了。既然GCM Server能通过API Key和registration id识别packagename,那restricted_package_name是不是显得有点多余?答案并非如此,我们只是说GCM Server可以通过API Key和registration id分别获取对应的packagename并校验其一致性,但不代表GCM Server有这样做!一切靠实际结果来验证。

      接下来,我们就来做一下测试:

前期准备:

* 一台安卓设备

* APP 1,对应Server 1、SenderId 1、API Key 1

* APP 2,对应Server 2、SenderId 2、API Key 2

* 不加restricted_package_name字段

测试案例 1:验证“GCM Server是否会校验API Key与registration id的一致性”

为了好理解一点,我们可以假设这样一个场景:4月1日想恶作剧一下,打算用我们的服务器往别人家APP推送一条搞怪的消息。

注意:在案例中registration id简称为token

测试过程:

1.APP 2通过SenderId 2生成一个token 22(22表示由APP 2利用SenderId 2生成的)。

2.Server 1拿到这个token 22,通过API Key 1推送消息到token 22。

测试结果:

GCM Server返回“MismatchSenderId”的错误信息。

测试案例 2:验证“GCM Server是否会校验API Key与registration id对应packagename的一致性”

同样,我们可以假设这样一个场景:一个黑客破解了我们APP的源码,拿到我们的SenderId,然后自己写一个APP利用这个SenderId生成对应token,并发给我们服务器注册,这样我们服务器推送消息时也会推给黑客的APP。

测试过程:

1.APP 2通过SenderId 1生成一个token 21(21表示由APP 2利用SenderId 1生成的);

2.Server 1拿到这个token 21,通过API Key 1推送消息到token 21。

测试结果:

Server 1推送成功,APP 2能够接收到推送消息。

测试案例 3:为了进一步验证,我们让Server 1同时往token 11、token21推送同一条消息,结果APP1、APP2都能接收到推送消息。

结论:

1.GCM Server会校验API Key与registration id的一致性。

2.GCM Server不会校验API Key与registration id对应APP packagename的一致性。

      以上,我们就可以明白了,只要“API Key”与“registration id对应的SenderId”能够匹配上,就可以推送成功。GCM Server并不管是哪一个应用!restricted_package_name的作用不言而喻。

>> 同样,我们对此进行了验证。

测试案例 4:在基于案例3的基础上,加入restricted_package_name。首先赋以APP 1的packagename,结果是:token 11(APP 1)推送成功,token 21(APP 2)报“Invalid Package Name”错误信息;其次改为APP 2的packagename,结果是:token 11(APP 1)报“Invalid Package Name”错误信息,token 21(APP 2)推送成功。

为什么GCM Server不校验?

这也不能说是Bug,可能是Google工程师觉得没有必要,也可能是GCM允许同个开发者的多个应用可以共享同一套API Key和SenderId吧。

questions about security nature of GCM这个帖子中,一位开发者提出了类似案例2中的场景,对此,Google工程师在答复中发布了“加入restricted_package_name字段”的消息,并且指出真正的问题--“为什么APP 2可以在Server 1上注册token?”他建议:向Server注册token时,应进行加密处理或者一定的校验,以保证token的合法性。

总结

GCM 同一套API Key和SenderId允许发给多个应用,可以通过restricted_package_name来指定某个应用。


参考文章

Implementing GCM Server

groups.google.com/forum/#!topic/android-gcm/M-EevBitbhQ

android - Why is restricted_package_name used? - Stack Overflow

developers.google.com/cloud-messaging/http-server-ref#error-codes

developers.google.com/android/reference/com/google/android/gms/iid/InstanceID.html#getToken(java.lang.String, java.lang.String)

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的阅读 13,430评论 5 6
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • 第一次知道奥黛丽赫本是因为电影《罗马假日》,是在2年前无意中赏析的一部经典。我震惊世间原来还存在过这样美丽,优雅的...
    海鸥老师阅读 1,184评论 8 29
  • 七夕,现在是国内的凌晨三点,美国的下午三点,探哥睡着了,我刚结束一段忙碌,刚才微信问他,如果我在国内,七夕节我们干...
    心念随笔阅读 299评论 0 1