Adding a Method Protected by OAuth
Any client can access your Endpoints API methods unless you protect them with OAuth 2.0. In some scenarios, you may want to restrict access to some or all of the API methods.
To protect a method in the backend API, you need to do two things:
- Add a
Userparameter to the method you wish to protect. - Add the email scope to your
@Apiannotation. - Specify a
clientIdswhitelist in the@APIannotation. (For Android devices only, you must also specifyaudiences.)
Adding an OAuth 2.0-protected method
To add the User parameter:
-
Import the App Engine User API in your API class:
import com.google.appengine.api.users.User; -
Add a parameter of type User to the API method you wish to protect, as shown for the method
greetings.authedin the snippet below:@ApiMethod(name = "greetings.authed", path = "greeting/authed") public HelloGreeting authedGreeting(User user) { HelloGreeting response = new HelloGreeting("hello " + user.getEmail()); return response; } -
Add a
Constants.javaclass for the client IDs you will be adding, as follows:package com.google.devrel.samples.helloendpoints; /** * Contains the client IDs and scopes for allowed clients consuming the helloworld API. */ public class Constants { public static final String WEB_CLIENT_ID = "replace this with your web client application 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"; public static final String API_EXPLORER_CLIENT_ID = com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID; }Notice that the Android audience is set to the value of the web client ID. (You only use
audiencesfor Android clients.) Notice also that we put the email scope and API Explorer client ID constants here to keep the API annotation cleaner. The API Explorer client ID is needed if you want to use the Explorer to test your backend API without building your own client.Also, in the snippet above, except for the API Explorer client ID, which we need for testng, we show only dummy values for web, Android, and iOS clients. You replace each of these with a real client ID when you add the corresponding client.
-
In your
Greetings.javaclass, modify the @Api annotation to add the client IDs, and add the scopes argument, specifying the email scope as shown:@Api( name = "helloworld", version = "v1", scopes = {Constants.EMAIL_SCOPE}, clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID, Constants.IOS_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID}, audiences = {Constants.ANDROID_AUDIENCE} )Although you can add other scopes, you must always include the email scope if you use OAuth.
-
Deploy the backend you just created to App Engine by invoking the command
mvn appengine:update -
The first time you deploy, you may be prompted to supply your Google account email and a password before deployment is allowed. Follow the prompts to supply these.
-
When the backend finishes deploying it will run at the URL
www.your-appengine-app-id.appspot.comwithyour-appengine-app-idbeing the project ID you created during setup and supplied inappengine-web.xmlduring configuration. Open API Explorer at that location by visiting this URL in your browser:http://your-appengine-app-id.appspot.com/_ah/api/explorer -
In the API Explorer, click helloworld API > helloworld.greetings.authed.
-
In the upper right of the API Explorer page, locate the toggle control labeled Authorize requests using OAuth 2.0 and click it On.
-
You'll be prompted to manually supply a scope: supply the value
https://www.googleapis.com/auth/userinfo.emailand click Authorize. -
Click Execute and observe the authorization in the request, and a greeting with your user name in the response.
Code summary
The main things to note in this sample code are the User parameter and the clientIds whitelist.
Why the User param is required
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 coming in from the client has a valid auth token or is in the
list of authorized clientIDs, the backend 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 User to
null.
Your own code must handle both the case where User is null and the case where
there is a valid User. If there is no User, for example, you could choose
to return a not-authenticated error or perform some other desired action. In
this tutorial, we omit this handling.
clientIds and audiences
The IDs in the clientids whitelist are values created for clients in the Google API console. Only those clients whose IDs are in the clientIds whitelist can access the protected method.
Although not shown in this tutorial, if one of the clients is an Android device,
you must also supply the audiences attribute.
For more information on obtaining client IDs, see Using OAuth 2.0 with Endpoints.
Next...
This completes the tutorial.
For the advanced topics such as using datastore and creating clients of the API backend, see the following:
- The Tic Tac Toe sample, which shows how to build a backend that uses datastore.
- Using Endpoints in an Android Client
- Using Endpoints in an iOS Client
- Using Endpoints in a JavaScript Client.