唯一识别 Android 用户的侵入性最小的方法
Least invasive way to uniquely identify Android user
您如何唯一地识别安装了您的应用的用户,以便:
- 如果他们删除并重新安装您的应用程序,您就会知道是他们干的;
- 如果他们将您的应用程序安装在他们打算同时使用的第二台设备上,您会知道是他们吗?
举个例子,我看到 Netflix 应用程序会自动 link 到您的桌面帐户,无需任何用户交互。我猜他们使用 accountManager.getAccounts()
或类似的方法,因为他们还需要 GET_ACCOUNTS
权限。但当然,该权限被标记为 Protection level: dangerous
。是否有任何侵入性较小或可能令人担忧的技术来做到这一点?
回答这个问题的关键是既简单(对用户而言)又微创。 Android 提供了大量的方法来识别用户,其中许多方法涉及刺穿用户的隐私,如果这是唯一的方法,我会做我现在做的(可选的电子邮件注册)。我只想让我的应用程序知道用户是否已经在安装过程中在我的系统中注册,而无需采访用户(username/password、电子邮件地址、第三方 OAuth 等)。
我的主要原因是:
- 我不希望来自重新安装后内容孤立的用户的支持请求;和
- 我不想托管很多孤立的内容。
我认为最好的方法是使用 Google or Facebook 实现登录。这对用户来说是非常无缝的,足够安全(因为 Google 和 Facebook 被认为是可信的),你不需要实现你的电子邮件注册,你将拥有跨设备的身份。
看看Firebase Authentication。它非常无缝,不需要太多努力即可融入。此外,它不会对最终用户造成干扰或麻烦。
这是 Google 的 video tutorial。
编辑:
如果您的用户确定拥有带有 phone 号码的蜂窝设备,您可以使用 AccountKit。这也是他们所说的 OTA(一次性身份验证)。 AccountKit 仅使用用户 phone 号码来验证和验证用户。
编辑:
Firebase 身份验证现在具有 'Phone Verification' 功能,类似于上面提到的 AccountKit。两者都是很好的服务。但是,Firebase phone 验证让您可以从头开始创建自己的 UI(这意味着比 AccountKit 更好的控制)。另外,如果您不想 UI,您可以随时使用 FirebaseUI
如果您的应用仅 Android 并且您希望在不为用户创建任何帐户的情况下提供身份,我相信使用 Google 帐户 name/id 是最佳选择( Accessing Google Account Id /username via Android) 因为您必须在 Android phone 上使用 Google 帐户(除非您将其设为 root,删除 Google Play 服务等)。
如果您只想解决问题的第一点(重新安装后识别),有一个设备 ID -Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
虽然它不是 100% 可靠(f.e 恢复出厂设置会重置此值)
实现此类功能的标准是通过 JSON web tokens (JWT) 与标准 restful api 流量的结合使用。
假设您的 android 应用程序与 RESTful api 交互所有 crudlike 操作和业务逻辑,然后使用 JWT 作为您的 api 的身份验证标识符可以工作得很好。您可以在每个 JWT 中嵌入信息,允许您识别任何您喜欢的内容(数据库中的用户 ID、用户登录的设备 ID 等)。 JWT 本质上是一种数据结构,允许您存储供 API.
使用的信息
有关其工作原理的一些基础知识:
- 将 JWT 引入应用程序:用户使用 username/password 登录到应用程序。这
api 然后 returns 一个加密的 JWT,供客户端用于所有未来的请求。不要试图做
自己加密。任何可以处理 api 服务的语言
将为此提供图书馆。
使用JWT中的信息:JWT本身就是一个数据结构。例如,它可能看起来像这样:
{
user_id: 1,
device_id: 44215,
device_os: android,
}
您的 api 将在提供 JWT 时对其进行解密
通过请求 header 进行身份验证,然后在
session.
的上下文
如果您提供 api 使用的语言,那么我可能会推荐一个库。
最后,我将参考您提交的最终要求,该要求基本上表明您不想在安装过程中采访用户。如果我理解您的意思,您希望用户能够简单地安装应用程序并开始使用它而无需提供身份验证凭据,那么就没有办法安全地实现这一点。您也许可以想出一个骇人听闻的方法来让它工作,但它从根本上来说是不安全的。
我已经通过推送通知实现了一些看起来与你的东西不太相似的东西,如果用户卸载了我的应用程序(并且从注册 ID 我得到了用户),我会得到错误,如果他重新安装,他会得到一个新的注册id,尝试获取不同设备的用户UUID
我认为最简单的方法是使用 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();
}
您如何唯一地识别安装了您的应用的用户,以便:
- 如果他们删除并重新安装您的应用程序,您就会知道是他们干的;
- 如果他们将您的应用程序安装在他们打算同时使用的第二台设备上,您会知道是他们吗?
举个例子,我看到 Netflix 应用程序会自动 link 到您的桌面帐户,无需任何用户交互。我猜他们使用 accountManager.getAccounts()
或类似的方法,因为他们还需要 GET_ACCOUNTS
权限。但当然,该权限被标记为 Protection level: dangerous
。是否有任何侵入性较小或可能令人担忧的技术来做到这一点?
回答这个问题的关键是既简单(对用户而言)又微创。 Android 提供了大量的方法来识别用户,其中许多方法涉及刺穿用户的隐私,如果这是唯一的方法,我会做我现在做的(可选的电子邮件注册)。我只想让我的应用程序知道用户是否已经在安装过程中在我的系统中注册,而无需采访用户(username/password、电子邮件地址、第三方 OAuth 等)。
我的主要原因是:
- 我不希望来自重新安装后内容孤立的用户的支持请求;和
- 我不想托管很多孤立的内容。
我认为最好的方法是使用 Google or Facebook 实现登录。这对用户来说是非常无缝的,足够安全(因为 Google 和 Facebook 被认为是可信的),你不需要实现你的电子邮件注册,你将拥有跨设备的身份。
看看Firebase Authentication。它非常无缝,不需要太多努力即可融入。此外,它不会对最终用户造成干扰或麻烦。
这是 Google 的 video tutorial。
编辑: 如果您的用户确定拥有带有 phone 号码的蜂窝设备,您可以使用 AccountKit。这也是他们所说的 OTA(一次性身份验证)。 AccountKit 仅使用用户 phone 号码来验证和验证用户。
编辑: Firebase 身份验证现在具有 'Phone Verification' 功能,类似于上面提到的 AccountKit。两者都是很好的服务。但是,Firebase phone 验证让您可以从头开始创建自己的 UI(这意味着比 AccountKit 更好的控制)。另外,如果您不想 UI,您可以随时使用 FirebaseUI
如果您的应用仅 Android 并且您希望在不为用户创建任何帐户的情况下提供身份,我相信使用 Google 帐户 name/id 是最佳选择( Accessing Google Account Id /username via Android) 因为您必须在 Android phone 上使用 Google 帐户(除非您将其设为 root,删除 Google Play 服务等)。
如果您只想解决问题的第一点(重新安装后识别),有一个设备 ID -Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
虽然它不是 100% 可靠(f.e 恢复出厂设置会重置此值)
实现此类功能的标准是通过 JSON web tokens (JWT) 与标准 restful api 流量的结合使用。
假设您的 android 应用程序与 RESTful api 交互所有 crudlike 操作和业务逻辑,然后使用 JWT 作为您的 api 的身份验证标识符可以工作得很好。您可以在每个 JWT 中嵌入信息,允许您识别任何您喜欢的内容(数据库中的用户 ID、用户登录的设备 ID 等)。 JWT 本质上是一种数据结构,允许您存储供 API.
使用的信息有关其工作原理的一些基础知识:
- 将 JWT 引入应用程序:用户使用 username/password 登录到应用程序。这 api 然后 returns 一个加密的 JWT,供客户端用于所有未来的请求。不要试图做 自己加密。任何可以处理 api 服务的语言 将为此提供图书馆。
使用JWT中的信息:JWT本身就是一个数据结构。例如,它可能看起来像这样:
{ user_id: 1, device_id: 44215, device_os: android, }
您的 api 将在提供 JWT 时对其进行解密 通过请求 header 进行身份验证,然后在 session.
的上下文
如果您提供 api 使用的语言,那么我可能会推荐一个库。
最后,我将参考您提交的最终要求,该要求基本上表明您不想在安装过程中采访用户。如果我理解您的意思,您希望用户能够简单地安装应用程序并开始使用它而无需提供身份验证凭据,那么就没有办法安全地实现这一点。您也许可以想出一个骇人听闻的方法来让它工作,但它从根本上来说是不安全的。
我已经通过推送通知实现了一些看起来与你的东西不太相似的东西,如果用户卸载了我的应用程序(并且从注册 ID 我得到了用户),我会得到错误,如果他重新安装,他会得到一个新的注册id,尝试获取不同设备的用户UUID
我认为最简单的方法是使用 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();
}