Adding Authorization to the API Backend

This page describes how to restrict all or part of your API backend to only authorized client apps.

For information on authentication from the perspective of keeping the backend secure, see the blog post Verifying Back-End Calls from Android Apps.

Before you begin

Create and annotate your backend API code.

Understanding the process

To restrict all or part of your API to only authorized apps, you must:

  1. Specify the client IDs (clientIds) of apps authorized to make requests to your API backend.
  2. Add a User parameter to all exposed methods to be protected by authorization.
  3. Generate the client library again for any Android clients
  4. Redeploy your backend API.
  5. If you have an Android client, update the regenerated jar file to your Android project.
  6. If you have an iOS client, regenerate the Objective-C library.

Specifying authorized clients in the API backend

You must specify which clients are allowed to access the API backend by means of a whitelist of client IDs. A client ID is generated by the Google Cloud Platform Console from a client secret, such as the SHA1 fingerprint of a key used to secure an Android app, or from the Bundle ID/Apple Store ID pair for an iOS app, as described in Creating OAuth 2.0 Client IDs. At runtime, a client app is granted the authorization token it needs to send requests to the API backend if its client secret matches one contained in a client ID within the API backend's client ID whitelist.

To specify which clients can be authenticated by your API backend:

  1. Get a complete list of the client IDs of the clients that you want to grant access to. This list is a list of OAuth 2.0 client IDs obtained for your project following the instructions in Creating OAuth 2.0 Client IDs.
  2. In the clientIds attribute of the @Api or @ApiMethod annotations for your API, supply the list of client IDs that you want to authenticate:
    • For an iOS app, supply its iOS client ID in the clientIds whitelist.
    • For a javascript app, supply its web client ID in the clientIds whitelist.
    • For an Android app, you must supply both its Android client ID and a web client ID in clientIds whitelist. (You must add that same web client ID to the audiences list as shown next.)
  3. If you have an Android client, you must also supply the audiences attribute for the @Api annotation, set to the web client ID mentioned in the preceding step. The same web client ID must be in both clientIds and audiences.

The following sample snippet shows how to supply client IDs for a JavaScript client, for an iOS client, and an Android client:

/** An endpoint class we are exposing */
@Api(name = "myApi",
    version = "v1",
    namespace = @ApiNamespace(ownerDomain = "helloworld.example.com",
        ownerName = "helloworld.example.com",
        packagePath = ""))
/**
 * Contains the client IDs and scopes for allowed clients consuming your API.
 */
public class Constants {
  public static final String WEB_CLIENT_ID = "replace this with your web client ID";
  public static final String ANDROID_CLIENT_ID = "replace this with your Android client ID";
  public static final String IOS_CLIENT_ID = "replace this with your iOS client ID";
  public static final String ANDROID_AUDIENCE = WEB_CLIENT_ID;

  public static final String EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email";
}

In the snippet, note the use of a class to map constants to the actual client ID values so you need only make changes in one place whenever you change the client IDs. Notice also that audiences is set to the web client ID value.

Adding a user parameter to methods for auth

When you declare a parameter of type User in your API method, the API backend framework automatically authenticates the user and enforces the authorized clientIds whitelist, ultimately by supplying the valid User or not. If the request from the app has a valid auth token or is in the list of authorized clientIDs, the framework supplies a valid User to the parameter. If the incoming request does not have a valid auth token or if the client is not on the clientIDs whitelist, the framework sets the User parameter to null. Your own code must handle the null case and the non-null case, as shown below.

To add a User param to your method:

  1. Add a parameter of type User to each class method you wish to require authorization for, as shown in the following snippet:
/** A simple endpoint method that takes a name and says Hi back */
@ApiMethod(
    name = "sayHiUser",
    httpMethod = ApiMethod.HttpMethod.GET)
public MyBean sayHiUser(@Named("name") String name, User user)
    throws OAuthRequestException, IOException {
  MyBean response = new MyBean();
  response.setData("Hi, " + name + "(" + user.getEmail() + ")");

  return response;
}

If an incoming client request has no authorization token or an invalid one, user is null. In your code, you need to check whether user is null and do ONE of the following, depending on the condition:

  • If the user is non-null, perform the authorized action.
  • If the user is null, throw an OAuthRequestException.
  • Alternatively, if the user is null, perform some action for an unauthorized client access if some sort of unauthorized access is desired.

Send feedback about...