【问题标题】:Least invasive way to uniquely identify Android user唯一识别 Android 用户的侵入性最小的方法
【发布时间】:2017-02-07 04:45:51
【问题描述】:

您如何唯一标识安装了您的应用的用户,以便:

  1. 如果他们删除并重新安装您的应用,您就会知道是他们;
  2. 如果他们将您的应用安装在他们打算同时使用的第二台设备上,您会知道是他们吗?

例如,我看到 Netflix 应用会自动链接到您的桌面帐户,而无需任何用户交互。我猜他们使用accountManager.getAccounts() 或类似方法,因为他们还需要GET_ACCOUNTS 权限。但当然该权限标记为Protection level: dangerous。是否有任何技术可以做到这一点侵入性较小或可能令人担忧?


回答这个问题的关键是简单(对用户而言)和微创。 Android 提供了很多方法来识别用户,其中许多方法涉及刺穿用户的隐私,如果这是唯一的方法,我会做我现在做的事情(可选的电子邮件注册)。我只想让我的应用程序知道用户是否已经在我的系统中注册,而无需采访用户(用户名/密码、电子邮件地址、第三方 OAuth 等)。

我的主要原因是:

  1. 我不希望重新安装后孤立其内容的用户提出支持请求;和
  2. 我不想托管大量孤立的内容。

【问题讨论】:

  • 我认为这是GET_ACCOUNTS 拥有dangerous 级别的原因之一。如果您根据帐户跟踪谁安装了该应用程序,那么您在某种程度上会收集个人信息。尽管有关联的帐户,但同时使用的设备之间基本上没有连接,我想不出任何办法。
  • 我完全同意。不过,这里的用例非常常见——想想照片应用程序。用户安装应用程序,我创建一个帐户,他们创建内容,我将其与他们的帐户相关联——其中一些是私有的,一些是共享的。我希望该帐户能够跨设备持续存在,而不会用“可怕的权限”吓到用户。我希望 Android 有一个“GUID”,它对每个发布者的用户都是唯一的,因此 com.mycompany.app1com.mycompany.app2 看到相同的值或类似的东西。但我可以明白为什么目前这行不通。
  • 在这种情况下它会很有用,你是对的。另一方面,它也可能会吓到用户,让他们的部分私人内容“神奇地”出现在另一台设备上。也许如果您在许可请求期间彻底解释许可,这将有助于消除恐惧。这也将允许用户选择他是否希望将他的内容限制在一个设备上。
  • 也许使用数字的 SMS 身份验证比社交网络上的 OAuth 更容易接受?只是一个建议
  • @tar,恕我直言,这个问题有很多变体,是的,但我的确切问题与 a) 最小权限(不要惊动用户)和 b) 尊重用户隐私有关。如果您可以在 SO 上找到这个确切的问题,请将其发布在下面或将其标记为重复。如果您不同意这是我要问的问题,我不知道该建议什么。我已经尽量把这个问题说清楚了。

标签: android identity android-permissions


【解决方案1】:

看看Firebase Authentication。它非常无缝,不需要太多努力来整合。此外,它不会让最终用户感到打扰或麻烦。

这是由 Google 提供的 video tutorial

编辑: 如果您的用户确定拥有带有电话号码的蜂窝设备,您可以使用AccountKit。这也是他们所说的OTA(一次性验证)。 AccountKit 仅使用用户电话号码来验证和验证用户。

编辑: Firebase 身份验证现在具有类似于上面提到的 AccountKit 的“电话验证”功能。两者都是很好的服务。但是,Firebase 电话验证可让您从头开始制作自己的 UI(这意味着比 AccountKit 更好的控制)。另外,如果您不想制作 UI,可以随时使用FirebaseUI

【讨论】:

  • 我会接受这个答案,因为我认为它让我最接近我的目标,尽管下面有一些非常有趣的想法。 @assem-mahrous 建议的跨设备通知系统是最有趣的(尽管我不确定它在安装中是否持久/确定)。对我而言,决定它的是 Firebase 允许“匿名登录”,因此用户可以立即进入应用程序、探索、构建自己的内容,然后当他们感到投入并信任它时,他们可以将自己的身份升级到他们的 Google 帐户(或 FB 或电子邮件/密码)。他们可以强制执行单一帐户。
  • @Andrew 当您向用户发送推送时,您可以获得一组用户如何通过静默推送卸载您的应用程序并在您的应用程序中处理它,即您不会向用户显示任何通知,您只会收到成功的响应和失败
【解决方案2】:

我已经通过推送通知实现了一些看起来与你的东西不太相似的东西,如果用户卸载了我的应用程序(并从注册 id 我得到用户),我会收到错误,如果他重新安装,他会获得一个新的注册 id ,并尝试获取不同设备的用户 UUID

【讨论】:

  • 谢谢。您是使用 Firebase 还是 GCM 来接收 UID?此外,您是否知道未经身份验证的用户是否会在她拥有的两台设备(例如手机和平板电脑)上收到相同的 UID?我很确定公共 API 无法做到这一点,但如果 Google 使用私有 API,这可能是可能的。
  • firebase 但由 laravel 在我的后端实现,每个用户都会获得一个唯一的 Token ,如果他卸载并重新安装应用程序,他将获得一个新的 Token ,唯一独特的是 UUID 我什至之前得到它注册到我的应用程序以便能够跟踪他
【解决方案3】:

我认为最简单的方法是使用 UUID 并将哈希存储在 sharedPreferences 上。您应该尽早在应用中生成 UUID。

sharedPrefs = context.getSharedPreferences(APP_SHARED_PREFS,Activity.MODE_PRIVATE);
if (sharedPrefs.getString("YOUR-KEY-TO-THE-UUID") == null || "".equals(sharedPrefs.getString("YOUR-KEY-TO-THE-UUID"))){
    prefsEditor = sharedPrefs.edit();
    prefsEditor.putString("YOUR-KEY-TO-THE-UUID", UUID.randomUUID().toString());
    prefsEditor.commit();
}

【讨论】:

  • 如果用户从设备上卸载应用程序,这将不起作用。如果用户卸载应用程序,SharedPreference 数据将被删除
【解决方案4】:

我认为最好的方法是使用GoogleFacebook 实现登录。这对用户来说是非常无缝的,足够安全(因为谷歌和 Facebook 被认为是可信的),您不需要实现您的电子邮件注册,并且您将拥有跨设备的身份。

【讨论】:

  • 感谢您的回答。如果他们没有谷歌/Facebook?我想我可以使用 Twitter。没有推特?我想也许是 Foursquare。没有四方?然后微博。然后是爱奇艺。然后是 Fitbit、Mixi 和 Netflix。这是一条无限回归的道路。然后是用户是否愿意将您与他们的 OAuth 身份联系起来的问题——以及您是否愿意将您的应用程序和用户群连接到该提供商。我个人从不觉得点击那个按钮很舒服(所以是我目前在任何地方连接的唯一东西)。我认为它放弃了太多而回报太少了。
  • 这由你决定,我只是建议了对用户最安全且在大多数情况下都有效的选项
  • @Andrew,按照你的想法,没有什么对你有用。如果您拥有 Android 设备,则无论如何都必须使用 Google 帐户进行设置。如果有人运行了一些奇怪的根植于 Android 的图像并且没有 facebook 或 twitter 帐户,那么我们已经在谈论大海捞针了。而且这完全不是无限回归。如果用户没有这两个帐户,则您可以为他们提供几个简单的选项,他们只需使用他们的电子邮件进行注册。哦,如果他们没有电子邮件怎么办? :) 你知道我在说什么吗?
  • @AndrejJurkin,我得到了人们的烦恼,我明白你在说什么。我只是试图找到功能、易用性、易于支持和隐私的最佳平衡,我在这里看到了一些很好的建议。我总是很失望,但并不感到惊讶,这么多开发人员从未考虑过社交登录的隐私成本。在国际上,它定义。是无限倒退:FB在中国被封;微博在非洲闻所未闻; Twitter 经常在 ME 中被屏蔽。此外,大多数社交网站都允许您删除链接的应用程序,这对保护用户隐私很有好处,但也是一种支持。
  • @Andrew,使用 Google 登录的隐私成本到底是多少? :) 你总是知道你会分享什么,如果你不喜欢这些要求,那么这个应用程序可能不适合你。默认情况下,您只分享非常基本的信息。当我在应用程序中看到 google 或 fb 登录按钮时,我总是很高兴。这样我就可以快速设置帐户,而不是浪费时间填写一些注册表单。
【解决方案5】:

如果您的应用仅适用于 Android,并且您希望在不为用户创建任何帐户的情况下提供身份,我相信使用 Google 帐户名称/ID 是最佳选择 (Accessing Google Account Id /username via Android),因为您必须在Android 手机(除非你根它,删除 Google Play 服务等)。

如果您只想解决问题的第一点(重新安装后识别),则设备 ID -Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID); 虽然不是 100% 可靠(例如出厂重置会重置此值)

【讨论】:

  • 感谢您的回答。我认为Secure.ANDROID_ID 正在接近满足我在重新安装应用程序或清除设备数据方面的担忧的答案,尽管出厂重置问题肯定是美中不足。我假设单个用户的 ADROID_ID 会因设备而异。
【解决方案6】:

实现此类功能的标准是通过使用JSON web tokens (JWT) 与标准的restful api 流量结合。

假设您的 android 应用程序与一个 RESTful api 进行交互以实现所有 crudlike 操作和业务逻辑,那么使用 JWT 作为您的 api 的身份验证标识符可以很好地工作。您可以在每个 JWT 中嵌入信息,以便您识别您喜欢的任何内容(数据库中的用户 ID、用户登录的设备 ID 等)。 JWT 本质上是一种数据结构,允许您存储 API 使用的信息。

有关其工作原理的一些基础知识:

  1. 将 JWT 导入应用程序:用户使用其用户名/密码登录应用程序。这 然后,api 返回一个加密的 JWT,供客户端用于所有未来的请求。不要试图做 自己加密。任何可以处理提供 api 的语言 将为此提供库。
  2. 在 JWT 中使用信息:JWT 本身就是一个数据结构。例如,它可能看起来像这样:

    { user_id: 1, device_id: 44215, device_os: android, }

    您的 api 将在提供 JWT 时对其进行解密 通过请求标头进行身份验证,然后在 会话的上下文。

如果您提供您的 api 使用的语言,那么我可能会推荐一个库。

最后,我将参考您提交的最终要求,该要求实质上表明您不希望在安装过程中与用户进行面谈。如果我理解您的意思,您希望用户能够简单地安装应用程序并开始使用它而不提供身份验证凭据,那么就无法安全地实现这一目标。你也许可以想出一个骇人听闻的方法来让它工作,但它从根本上是不安全的。

【讨论】:

  • JWT 可以很好地跨会话维护状态(尽管正如许多人在其他地方解释的那样,JWT 在维护状态持久性方面较差。)我的问题是专门关于在新实例之间维护身份的。这正是我的问题,我已经提供了一种方法,由 NetFlix 安全且无恶意地完成。
  • 当 netflix 检测到您已安装桌面版本(或在 android 应用程序上检测到已安装 android 应用程序),然后使用在该应用程序中找到的凭据通过浏览器授予访问权限时,几乎可以肯定只需从本地应用程序中检索 JWT 并使用它进行身份验证。它可能需要一个新的独特的,以区别于用于分析的桌面应用程序,但关键是为了安全起见,您需要在每台设备上至少采访一次用户。
  • 如果您关心的只是在应用程序安装之间保留 JWT,那么您必须将数据存储在“正常”应用程序之外。例如,您可以在 SD 卡或文件系统上创建加密文件。
  • FS 存储无疑是解决此问题的一种方法。我想说它提供了与Secure.ANDROID_ID 相同的优点和缺点,除了另外,所需的权限标记为Protection level: dangerous。就个人而言,我觉得使用WRITE_EXTERNAL_STORAGE 比使用GET_ACCOUNTS 更安全一些,因为有很多应用程序使用它,我几乎希望在安装某些东西时看到它。
  • 我不会为此使用 Secure.ANDROID_ID。首先,在我看来,这将是不安全的。其次,正如您所建议的,我认为从权限的角度来看,写入文件系统的侵入性似乎要小得多。第三,即使你忽略了安全隐患,它也不那么可靠。该值在不常见的情况下可能会发生变化,并且通常不如您自己的文件系统样式实现可靠。
猜你喜欢
  • 2010-10-05
  • 1970-01-01
  • 2020-02-22
  • 2015-07-11
  • 1970-01-01
  • 2011-04-27
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多