OAuth2
OAuth2
本示例演示了如何在 gRPC 上使用 OAuth2 代表用户进行身份验证的 API 调用。
通过阅读本文,您还将学习如何使用 Objective-C gRPC API 进行以下操作:
- 在 RPC 开始之前初始化和配置远程调用对象。
- 在调用中设置请求元数据元素,这些元素在语义上等同于 HTTP 请求头。
- 从调用中读取响应元数据,这些元数据等同于 HTTP 响应头和尾部。
本文假设您了解如何使用 Objective-C 客户端库进行 gRPC API 调用的基础知识,如基础教程和gRPC 简介中所述,并熟悉 OAuth2 概念,例如访问令牌。
示例代码和设置
有关示例源代码,请参阅gprc/examples/objective-c/auth_sample。要下载示例,请运行以下命令克隆此仓库:
git clone -b v1.71.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
cd grpc
git submodule update --init
然后将当前目录更改为 examples/objective-c/auth_sample
cd examples/objective-c/auth_sample
我们的示例是一个简单的应用程序,包含两个视图。第一个视图允许用户使用 Google 的 iOS 登录库 的 OAuth2 流程进行登录和退出。(本示例使用 Google 的库是因为我们要调用的测试 gRPC 服务需要 Google 账户凭据,但 gRPC 和 Objective-C 客户端库本身并不绑定于任何特定的 OAuth2 提供商)。第二个视图向测试服务器发起 gRPC 请求,使用了第一个视图获取的访问令牌。
注意
OAuth2 库需要应用程序向身份提供商(在本示例应用中为 Google)注册并获取一个 ID。应用的 XCode 项目是使用该 ID 配置的,因此您不应将此项目“原样”复制到您自己的应用中:这样做会导致您的应用在授权同意屏幕中被标识为“gRPC-AuthSample”,并且无法访问真实的 Google 服务。相反,请按照此处的说明 配置您自己的 XCode 项目。与其他 Objective-C 示例一样,您也应该安装 CocoaPods,以及生成客户端库代码的相关工具。您可以通过以下这些设置说明 获取后者。
试一试!
要试用示例应用,首先让 CocoaPods 为我们的 .proto 文件生成并安装客户端库:
pod install
(如果 CocoaPods 尚未在您的计算机缓存中拥有 OpenSSL,则可能需要编译它,这大约需要 15 分钟)。
最后,打开 CocoaPods 创建的 XCode 工作区,然后运行应用。
第一个视图,SelectUserViewController.h/m
,要求您使用 Google 账户登录,并授予 “gRPC-AuthSample” 应用以下权限:
- 查看您的电子邮件地址。
- 查看您的基本个人资料信息。
- “用于访问 Zoo 服务的测试范围”。
最后一个权限,对应于范围 https://www.googleapis.com/auth/xapi.zoo
,不授予任何实际能力:它仅用于测试。您可以随时注销。
第二个视图,MakeRPCViewController.h/m
,向位于 https://grpc-test.sandbox.google.com 的测试服务器发起 gRPC 请求,并在请求中附带访问令牌。测试服务仅验证令牌并在其响应中写入该令牌属于哪个用户,以及授予哪些范围的访问权限。(客户端应用程序已经知道这两个值;这是验证一切是否按预期进行的一种方式)。
下面的章节将逐步指导您了解如何在 MakeRPCViewController
中执行 gRPC 调用。您可以在MakeRPCViewController.m 中查看完整代码。
使用访问令牌创建调用
要进行身份验证调用,首先需要初始化一个 GRPCCallOptions
对象,并使用访问令牌配置它。
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.oauth2AccessToken = myAccessToken;
然后您需要使用此调用选项对象创建并开始您的调用。假设您有一个如下所示的 proto 服务定义:
option objc_class_prefix = "AUTH";
service TestService {
rpc UnaryCall(Request) returns (Response);
}
对于 AUTHTestService
类,会生成一个您已经熟悉的 unaryCallWithMessage:responseHandler:callOptions:
方法:
- (GRPCUnaryProtoRPC *)unaryCallWithMessage:(AUTHRequest *)message
responseHandler:(id<GRPCProtoResponseHandler>)responseHandler
callOptions:(GRPCCallOptions *)callOptions;
使用此方法以及您的请求选项对象生成 RPC 对象:
GRPCUnaryProtoRPC *rpc = [client unaryCallWithMessage:myRequestMessage
responseHandler:myResponseHandler
callOptions:options];
然后,您可以在稍后的任何时间使用此对象代表的 RPC,如下所示:
[rpc start];
提供访问令牌的替代方法
除了在创建 RPC 对象之前在 GRPCCallOptions
选项中设置 oauth2AccessToken
中之外,另一种方法允许用户在调用开始时提供访问令牌。
要使用此方法,首先在您的项目中创建一个符合 GRPCAuthorizationProtocol
协议的类。
@interface TokenProvider : NSObject<GRPCAuthorizationProtocol>
...
@end
@implementation TokenProvider
- (void)getTokenWithHandler:(void (^)(NSString* token))handler {
...
}
@end
创建 RPC 对象时,将此类的实例传递给调用选项 authTokenProvider
:
GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
options.authTokenProvider = [[TokenProvider alloc] init];
GRPCUnaryProtoCall *rpc = [client unaryCallWithMessage:myRequestMessage
responseHandler:myResponseHandler
callOptions:options] start];
[rpc start];
调用开始时,它将调用 TokenProvider
实例的 getTokenWithHandler:
方法,并带有一个回调 handler
,并等待回调。该 TokenProvider
实例可以在任何时候调用处理程序,为本次调用提供令牌并恢复调用过程。