From 3508c9a5b85e41b4a7c9a68e10a6838108232170 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 16 Jun 2015 22:21:48 -0700 Subject: Add README for the auth example --- objective-c/auth_sample/README.md | 174 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 objective-c/auth_sample/README.md diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md new file mode 100644 index 0000000000..06812323bc --- /dev/null +++ b/objective-c/auth_sample/README.md @@ -0,0 +1,174 @@ +#OAuth2 on gRPC: Objective-C + +This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on +behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: + +- Initialize and configure a remote call object before the RPC is started. +- Set request metadata elements on a call, which are semantically equivalent to HTTP request +headers. +- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. + +It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, +as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) +or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, +and familiarity with OAuth2 concepts like _access token_. + +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Create an RPC object and start it later](#rpc-object) +- [Set request metadata of a call: Authorization header with an access token](#request-metadata) +- [Get response metadata of a call: Auth challenge header](#response-metadata) + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/auth_sample`: +```shell +$ cd grpc-common/objective-c/auth_sample +``` + +Our example is a simple application with two views. The first one lets a user sign in and out using +the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). +(Google's library is used in this example because the test gRPC service we are going to call expects +Google account credentials, but neither gRPC nor the Objective-C client library is tied to any +specific OAuth2 provider). The second view makes a gRPC request to the test server, using the +access token obtained by the first view. + +Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider +(in the case of this example app, Google). The app's XCode project is configured using that ID, so +you shouldn't copy this project as is for your own app: It would result in your app being identified +in the consent screen as "gRPC-AuthSample", and not having access to real Google services. Instead, +configure your XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). + +As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) +installed, as well as the relevant tools to generate the client library code. You can obtain the +latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, first have Cocoapods generate and install the client library for our .proto +files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. + +The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to +give the "gRPC-AuthSample" app the following permissions: + +- View your email address. +- View your basic profile info. +- "Test scope for access to the Zoo service". + +This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't +grant any real capability: It's only used for testing. You can log out at any moment. + +The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at +https://grpc-test.sandbox.google.com, sending the access token along with the request. The test +service simply validates the token and writes in its response which user it belongs to, and which +scopes it gives access to. (The client application already knows those two values; it's a way to +verify that everything went as expected). + +The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is +performed. + + +## Create an RPC object and start it later + +The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated +client object. This shows how to initialize an object that represents the RPC, and configure it +before starting the network request. + +Assume you have a proto service definition like this: + +```protobuf +option objc_class_prefix = "AUTH"; + +service TestService { + rpc UnaryCall(Request) returns (Response); +} +``` + +A `unaryCallWithRequest:handler:` method is generated, with which you're already familiar, is +generated for the `AUTHTestService` class: + +```objective-c +[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... +}]; +``` + +And a second `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +not-yet-started RPC object: + +```objective-c +#import + +ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... + }]; +``` + +The RPC represented by this object can be started at any later time like this: + +```objective-c +[call start]; +``` + + +## Set request metadata of a call: Authorization header with an access token + +The `ProtoRPC` class has a `requestMetadata` property defined like this: + +```objective-c +@property(nonatomic, readwrite) NSMutableDictionary *requestMetadata; +``` + +Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call +is started. + +```objective-c +call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"My-Header": @"Value for this header", + @"Another-Header": @"Its value"}]; +``` + +If you have an access token, OAuth2 specifies it is to be sent in this format: + +```objective-c +@{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]} +``` + + +## Get response metadata of a call: Auth challenge header + +Analogously to the request metadata, the `ProtoRPC` class has a `responseMetadata` property defined +this way: + +```objective-c +@property(atomic, readonly) NSDictionary *responseMetadata; +``` + +Because gRPC metadata keys can be repeated, the values of the `responseMetadata` dictionary are +always `NSArray`s. Thus, to access OAuth2's authentication challenge header you write: + +```objective-c +call.responseMetadata[@"www-authenticate"][0] +``` + +Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the +response metadata are always ASCII strings in lowercase. -- cgit v1.2.3