Wear 中的身份验证

随着独立手表的就位,Wear 应用现在无需配套应用便可在手表上独立运行。这一新能力同时意味着,Android Wear 独立应用在需要访问云端数据时需要自行管理身份验证。Android Wear 支持通过几种身份验证方法来让独立 Wear 应用能够获得用户身份验证凭据。

目前,Android Wear 支持下列身份验证方法:

下文介绍如何将以上身份验证方法集成到您的 Wear 应用中。

Google Sign-in

Google Sign-In 允许用户使用其现有 Google 帐号登录。它能提供最佳用户体验并且易于支持,尤其是您已经在手持式设备应用中实现这些解决方案时。

Google Sign-in 是最受青睐的解决方案,因为它在 iOS 上同样表现出色。下文介绍如何完成基本的 Google Sign-In 集成。

先决条件

在您开始在 Wear 应用中集成 Google Sign-In 之前,必须配置一个 Google API 控制台项目,并建立您的 Android Studio 项目。如需了解详细信息,请参阅 Google Sign-In 入门集成指南

:如果您将 Google Sign-In 用于与后端服务器通信的应用或网站,则为您的后端服务器创建一个 OAuth 2.0 网络应用客户端 ID。该客户端 ID 不同于您的应用的客户端 ID。如需了解详细信息,请参阅启用服务器端访问

重要说明:如果您的应用与后端服务器通信,可通过使用 HTTPS 发送用户的 ID 令牌安全地识别该服务器上当前登录的用户。要了解如何在后端服务器上对用户进行身份验证,请参阅用后端服务器进行身份验证

在您的应用中集成 Google Sign-In

要在您的 Wear 应用中集成 Google Sign-In:

  1. 配置 Google Sign-in
  2. 添加 Google Sign-in 按钮
  3. 点击登录按钮时启动登录流程

配置 Google Sign-in 并构建 GoogleApiClient 对象

在您的登录 Activity 的 onCreate 函数中,配置 Google Sign-in 以请求您的应用所需的用户数据。然后,创建一个具有 Google Sign-in API 访问权和您所指定选项的 GoogleApiClient 对象。

// Configure sign-in to request the user's ID, email address, and basic
// profile. The ID and basic profile are included in DEFAULT_SIGN_IN.
// If you need to request additional scopes to access Google APIs, specify them with
// requestScopes().
GoogleSignInOptions.Builder signInConfigBuilder = new GoogleSignInOptions
        .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestEmail()
        .build();

// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified in the sign-in configuration.
mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this /* FragmentActivity */, this /OnConnectionFailedListener */)
        .addApi(Auth.GOOGLE_SIGN_IN_API, signInConfigBuilder)
        .build();

为您的应用添加一个 Google Sign-In 按钮

  1. 在您的应用的布局中添加 SignInButton
  2.  <com.google.android.gms.common.SignInButton
     android:id="@+id/sign_in_button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />
    
  3. 在您的应用的 onCreate() 函数中,注册您的按钮的 OnClickListener,以便用户只需点击该按钮即可登录。
  4. findViewById(R.id.sign_in_button).setOnClickListener(this);
    

创建一个 Sign-in Intent 并启动登录流程

点击登录按钮时,通过使用 getSignInIntent 函数创建一个 Sign-in Intent 处理您的 onCLick() 函数中的登录按钮点按,然后使用 startActivityForResult 函数启动该 Intent。

Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);

系统提示用户选择登录时使用的 Google 帐号。如果您请求的作用域超过了配置文件、电子邮件和 OpenID,系统还会提示用户授予对这些资源的访问权。

最后,在该 Activity 的 onActivityResult 函数中,使用 getSignInResultFromIntent 检索登录结果。在您检索登录结果后,可以使用 isSuccess 函数检查登录是否成功。如果登录成功,您可以调用 getSignInAccount 函数来获取 GoogleSignInAccount 对象,其中包含有关已登录用户的信息,例如用户的姓名。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...)
    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (signInResult.isSuccess()) {
            GoogleSignInAccount acct = signInResult.getSignInAccount();

            // Get account information
            mFullName = acct.getDisplayName();
            mGivenName = acct.getGivenName();
            mFamilyName = acct.getFamilyName();
            mEmail = acct.getEmail();
        }
    }
}

要查看实现 Google Sign-in 的示例应用,请参阅示例应用

OAuth 2.0 支持

Wear 为第三方应用提供 OAuth 2.0 支持,让它们能够通过网络 service 验证用户身份。考虑到 Wear 设备的屏幕空间有限,Android Wear OAuth 支持让独立手表应用能够通过手机完成 OAuth 身份验证流程。独立应用使用请求和响应网址模型来验证用户身份以及接收 OAuth 令牌来访问 service。

:如果您的 Wear 2.0 应用有配套的手机应用,请为您的 Wear 应用和该手机应用使用相同的软件包名称。

先决条件

在开始之前,请为您的后端服务器创建一个 OAuth 2.0 网络应用客户端 ID。该客户端 ID 不同于您的应用的客户端 ID。您可以在 Google API 控制台中为您的服务器查找或创建一个客户端 ID。

流程

  1. 用户使用第三方应用执行一项需要授权的操作。
  2. 第三方应用使用 Wear Services API sendAuthorizationRequest() 向 Android Wear 配套应用发送请求,以使用授权网址打开一个网页视图。
  3. 网址网站授权用户(要求用户提供用户名、密码,或许还执行某种双重身份验证等操作)。
  4. 授权成功或失败后,网站使用授权代码调用请求中指定的回调网址(指向应用的后端服务器)。
  5. 后端服务器用授权代码交换访问权,并从 OAuth 服务器刷新令牌。
  6. 后端服务器随后重定向响应,通过 Android Wear 配套应用转到第三方手表应用。
  7. Android Wear 配套应用收到该重定向后使用 Wearable Support API onAuthorizationResponse() 将来自服务器的整个响应发送回手表应用。
  8. 第三方应用解析来自授权网站的响应,并从响应中提取授权令牌
  9. 第三方应用在其未来请求中使用该授权令牌作为凭据。
alt_text

要实现以上授权流程,您需要执行以下操作:

  1. 创建客户端 ID 和客户端密钥
  2. 执行授权请求
  3. 处理授权响应

创建客户端 ID 和客户端密钥

使用 OAuth 2.0 的 Wear 应用必须创建客户端 ID客户端密钥,用于向 OAuth 提供程序表露应用身份。您需要建立一个 API 控制台项目来获得这些凭据。

执行授权请求

要执行向 OAuth 提供程序的授权请求,先创建一个客户端对象,您将使用它在您的 onCreate() 函数中发出 OAuth 2.0 请求。

:要确保手表转入微光模式时您的应用不会关闭,请在应用的 OAuth Activity 中启用 Always-on(通过 setAmbientEnabled)。如需了解有关微光模式下最佳做法的详细信息,请参阅保持应用可见页面。

@Override
public void onCreate(Bundle b) {
    super.onCreate(b);
    mOAuthClient = OAuthClient.create(this);
    …...
}

接下来,构建一个网址,其中包括用于获取令牌、您的服务器 OAuth 客户端 ID、重定向网址(指向您的后端服务器)以及响应类型的 OAuth 端点。

请求的网址与以下类似:

https://accounts.google.com/o/oauth2/v2/auth?response_type=code
&client_id="your_client_id_here";
&scope=https://www.googleapis.com/auth/plus.login
&redirect_uri=https://myserver.com

在您构建授权请求后,就可以使用 Wear Services API sendAuthorizationRequest() 向配套应用发送请求。

该请求触发对配套应用的远程过程调用 (RPC),这会使授权界面呈现在用户手机上。OAuth 2.0 提供程序验证用户身份,并征得用户的同意,让您的应用能够访问请求的作用域。响应使用您指定的重定向网址发送回您的后端服务器。

处理授权响应

授权成功或失败后,OAuth 2.0 服务器重定向到请求中指定的网址。如果用户批准此访问请求,则响应中将包含授权代码。如果用户不批准此请求,则响应中将包含错误消息。

响应将是查询字符串形式,如下所示:

https://myserver.com/oauthtokens?code=xyz

后端服务器收到授权代码后,可以使用授权代码交换访问令牌。然后后端服务器向注册为以下形式网址接收方的 Android Wear 手机应用返回一个 HTTP 302 重定向:https://wear.googleapis.com/3p_auth/app.html?full_suffix_from_redirect=com.your.package.name?accessToken=abc&refreshToken=xyz
手机应用验证响应网址,并使用 onAuthorizationResponse API 将响应传递给第三方手表应用。

:确保应用软件包名称是重定向网址中的第 3 个路径组成部分。因此,redirect_uri 必须等于 https://wear.googleapis.com/3p_auth/<receiving app's packagename>。例如,https://wear.googleapis.com/3p_auth/com.package.name

手表上的第三方应用从响应提取授权令牌,并在其未来请求中使用该授权令牌作为凭据。

// The callback provided will be called when the OAuth request completes.
mClient.sendAuthorizationRequest(Uri.parse(requestUrl), new MyOAuthCallback());
private class MyOAuthCallback extends OAuthClient.Callback {
    @Override
    public void onAuthorizationResponse(Uri requestUrl, Uri responseUrl) {
        super.onAuthorizationResponse(requestUrl, responseUrl);
        Runnable r =
            new Runnable() {
                public void run() {
                    acquireToken();
                    accessAPI();
                }
            };
    }
}

要查看此流程的完整实现,请参阅示例

:鉴于本示例的目的,手表将对令牌交换进行处理。作为最佳做法,将重定向 URI 设置为您自己的服务器网址,服务器可以在该网址上执行授权代码令牌交换。

通过数据层传递令牌

此选择仅对 Android 配对手表有效。手机上的配套应用可以通过 Wearable Data Layer 将身份验证数据安全地传送至 Wear 应用。凭据可以消息或数据项形式传送。

:我们建议您使用相同的软件包名称交付手机 APK 和手表 APK。这样手机和 Wear 应用便可通过 DataItem 层进行通信,以及执行从手机到手表的后台令牌传送以提供身份验证。

流程

您可以按照自己的业务逻辑使用 Data Layer API 传递凭据。下图描述了通过 Wearable Data Layer 获取令牌的其中一种方法。

alt_text

自定义代码身份验证

这种身份验证方法要求用户从外部来源(移动设备/平板电脑/PC)进行身份验证,然后通过输入获得的短生存期代码来证明其身份,并用它来交换其 Wear 设备上的身份验证令牌。在此方法中,您可以通过使用应用的登录模块或通过手动将任何第三方身份验证提供程序登录方法集成到应用的代码内,向您的 Wear 应用验证用户身份。尽管此身份验证方法需要人力工作和额外努力才能提高其安全性,如果您在独立 Wear 应用的早期需要身份验证,仍可使用此方法。

此设置的身份验证流程工作方式如下:

  1. 用户使用第三方应用执行一项需要授权的操作。
  2. 第三方 Wear 应用向用户呈现身份验证屏幕,并指示用户从指定网址输入代码。
  3. 用户切换到移动设备/平板电脑或 PC,启动浏览器,导航到在 Wear 应用上指定的网址,然后登录。
  4. 用户收到短生存期代码后使用 Wear 应用中的自带键盘将其输入 Wear 应用身份验证屏幕进行身份验证:

    alt_text

  5. 从此时开始,您可以使用输入的代码作为证据来证明这是正确的用户,并用该代码来交换在 Wear 设备上存储并加密的身份验证令牌,用于进行未来的身份验证调用。
alt_text