Google Cloud Endpoints Tutorial – Part 5

Welcome to Part 5 of the Google Cloud Endpoints Tutorial.

The full series:

  • Part 1 : We looked at writing a Google Cloud Endpoints class manually by using the various annotations and Exception classes that are available. We create a Quotes API that provided a JSON + REST based interface to manage Quotes (add, modify, delete and retrieve quotes).
  • Part 2 : We generated the Google Cloud Endpoints class from a JDO Annotated Entity class by using the Code Generation tools provided in the library.
  • Part 3 : Generated the Cloud Endpoints Client Library for Android and wrote an Android application that invokes the Endpoints API.
  • Part 4: We wrote a JavaScript client for our Endpoints API.
  • Part 5: Securing our API
  • Part 6: Calling a Secured API from a JavaScript client.
  • Part 7 : Calling a Secured API from an Android client.

I have also published a list of Cloud Endpoints Tips:

  1. Check Endpoint Deployment Status
  2. Throw the Right Exception Classes
  3. Understand Injected Types
  4. Understand @API and @APIMethod Annotations
  5. Using Cursor and Limit parameters
  6. The @APIResourceProperty Annotation

In this episode

Security is a key consideration for any application that you host on the public internet. This is especially important when you are writing an API for others to use in their client applications. You need to ensure that the API that you have written is secure, allows only authenticated users to perform operations and so on.

In this episode, we shall look at securing the Quotes API that we have written so far. This episode only focuses on securing the API implementation. Once, we are done with that, in the following episodes that will be published quickly, we shall see how to make authenticated calls from both a JavaScript client and an Android application.

What do you need ?

  • You have a working development environment for Google App Engine. This includes the Google Eclipse plugin.
  • The API Project 2 (Quotes Endpoint Project) loaded in your Development Environment. This project has now been updated to secure certain operations, which we shall cover in this episode. So, if you have an older version of it, you might want to sync with the latest code. Even if you do not want to load it, just follow along in the tutorial to see how to secure your API.

My Development Environment

This remains the same, no changes at all. My development environment is given below:

  • Eclipse Juno
  • Google Eclipse plugin with App Engine SDK 1.8.8.
  • Mac + Windows machine (I kept switching from one to another, to keep everyone happy ;-))

Securing the Quotes API

Let us recap quickly on what we have done so far. We have written a Quotes API hosted on Google App Engine that allows us to perform CRUD operations via a HTTP REST API. A Quote record contains a couple of attributes, the author and the famous quote that the author gave.

If you look at the API Methods, we had the following methods exposed:

Screen Shot 2014-01-12 at 4.21.42 PM

To secure the API, we need to first determine if we are interested in securing all the methods that we expose or only certain methods. This flexibility is provided to you by Google Cloud Endpoints.

So, what we are going to see in this operation is enabling security for one of the methods: insertQuote. What this means is that if you are not an authorized user, that any call to the insertQuote method will fail. Once you understand how to do it for one method, it should be straight forward for you to extend it to other methods.

Sounds good? Lets move on.

Adding Authorization

Google has clearly documented the steps that we need to follow to add authorization to our API and we will follow that as specified.

Step 1 : Specify the Client Ids

The first thing we need to decide is what kind of clients are we expecting for our API. The usual suspects are a Web client, Android client, iOS client and so on. What this means is that we need to create these client Ids and both the Server side i.e. our API Implementation and the Client need to be aware of these Client Ids, so that the Client can be identified with the Server.

To do that, I will assume that since you have been reading these tutorial series, you have also created an App Engine project. If not, this is the time to do it and there is no other way out from this :-)

To create the client Ids, you will need to visit the Google Cloud Console for your App Engine project. In case, you are yet to deploy your API to the App Engine instance, I suggest this is a good time to create the application.

In my case, I already deployed this API to an App Engine instance (mybackendapi). So I directly visit the Google Cloud Console for my account and from my list of projects, I select the particular API project (in my case again, it is the mybackendapi project)

You will see a similar screen as shown below:

Screen Shot 2014-02-14 at 8.34.27 PM

Go ahead and click on APIs & auth link from the left menu and then the Credentials link as shown below:

Screen Shot 2014-02-14 at 8.37.08 PM

We need to generate a Web Client here and in the later episode, I shall demonstrate how to generate an Android client. But for now, let us just generate the Web Client ID. 

Click on the Create New Client Id button that you see in RED. This lets you create Client Ids for Web, Android and more. You will see a screen as shown below:

cep-ep5-1

The Application Type should be fairly straightforward i.e. it is a Web Application client that we shall write in the next episode. The next field is very important. It allows you to specify an origin from where the JavaScript call will be made and which will need to be authenticated by the Google Authentication Layer. In our case, when the credentials are being provided, the call will be made from either our localhost application where we will run to do some testing or finally when we deploy it, it will be our App Engine application.

You can specify multiple origins here (one on each line). So I have specified the localhost and also the my appengine application origin. The redirect URI is not applicable here and is automatically populated for you. Let that be as is.

Click on the Create Client ID button. This will generate the Client Id and you will see that in your console as shown below:

Screen Shot 2014-02-14 at 8.45.01 PM

Note down the Client ID. You will need it in the next episode when we make make authorized calls from our JavaScript client.

The next step is important and is something that you might forget. It happened to me, at least the first time. 

Click on the Consent screen link. This is the screen that is shown when you are authorizing the application on your behalf. You can fill in all the details but at a minimum, you must fill our the Email address and Product name.

cep-ep5-2

Click on Save button to save your settings for the Consent Screen.

Now that we have created the Client Ids, we need to ultimately provide this information to our Server API i.e. Endpoints API. To help keep all the IDs in one place, Google documentation shows the use of a Constants.java file and that is a good approach to go with. So we will create a Constants.java file and place our Client Ids in that as shown below:

Note the following:

  • We have defined the constant WEB_CLIENT_ID that should contain the value of the Client ID that we just created.
  • The next thing to note is the EMAIL_SCOPE. This is the OAuth 2.0 Scope. 
  • The ANDROID_CLIENT_ID, we have not yet generated. But once we generate it (as we will see in a later episode, you will need to put it here).
  • There is also the ANDROID_AUDIENCE that is given the same value as the WEB_CLIENT_ID. We shall use this in later episode when we create our Android client.

Step 2 : Add the Client Ids, Scope and Audiences to your @API or @APIMethod

We need to first make a decision whether we want to protect all the methods or only some methods. If you want to protect all the methods, you need to deal with the @API annotation or if you are interested in protecting specific methods, then you need to worry about the @APIMethod (i.e. the methods in your class).

As described earlier, we are going to protect only the insertQuote method, so we shall we enhancing the @APIMethod annotation for the insertQuote method as shown below:

Let us take a look at the important points here:

  • We have added 3 attributes to the @APIMethod for the insertQuote method. They are scopes, clientIds and audiences as covered earlier.
  • Note that the clientIds also contains an additional one : com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID and this is required because we are going to use the API Explorer for testing out our API. Makes sense doesn’t it ?

Step 3 : Add the Add a User parameter to your methods

Keep your focus on the above Gist for the insertQuote method. For every method that you want to authorize for, you need to add a User parameter at the end as we have done. If the user is authorized correctly, an instance of the com.google.appengine.api.users.User  class will be passed in here.

But you will need to be careful here. You cannot assume that the object will be populated always. If the Authorization fails, the User object will be null. So you need to do your own little check here as we have.

We check for null value and it that is indeed the case, we throw a com.google.api.server.spi.response.UnauthorizedException, which will be translated by the Endpoints layer into a correct HTTP 401 Status Code. The rest of the code is the standard code from the previous episodes.

That is all  you need to do to the methods. In case you wish to apply this to other methods, you can do that.

Step 4 : Regenerate your APIs

This step is not really needed at this point till we revisit our client applications but safe to say that it is important that you generate the Client Libraries again because you have modified the details for the APIs. To generate your Client Libraries again, it should be familiar to you but I will say it again.

eclipse2

Testing your secured API via the API Explorer

All right ! We have done the hard work of securing the API ? Or have we … let’s find that out!

We will use our good friend, the API Explorer to help us out again. You could do this testing either in your local dev server environment or the live App Engine instance. Just keep in mind that the API explorer is available via the /_ah/api/explorer URL. Remember that we had provided the JavaScript Origins for both our localhost and the app engine instance when defined the Client ID and that is going to hold us good whether we test in our local environment or the live environment.

In my case, I am testing the same in my local dev environment. I visit http://localhost:8888/_ah/api/explorer and I visit the insertQuote method. Remember that is the method that we secured and want to test out.

We simply provide the Quote Author and Message and click on Execute. If you have done things carefully and correctly till now, you will see an error pop up as shown below. It clearly states that you need to be authenticated.

cep-ep5-3

Note that, the Response is correctly thrown back as we had done in our code. We had thrown an UnauthorizedException and that is translated back into a HTTP 401 Status Code correctly as shown below.

cep-ep5-4

Since we are using the API Explorer client over here, we need to login over here. In the right corner, you will find a Toggle as shown below:

cep-ep5-5

Click on the Toggle switch to turn it ON. This brings up the typically OAuth dance sequence. The first popup shows the SCOPE that we had defined on our API. Remember the EMAIL_SCOPE constant. That is selected by default. Simply click on the Authorize button.

cep-ep5-6

This will bring up a Google login. Just login or select the Account (in case you have multiple Google Accounts). Complete the Login successfully and you will be back in the API explorer with the Toggle switched on to ON as shown below:

cep-ep5-7

Now, fire off the insertQuote method again. And this time, all is well. Notice in the POST Request HTTP Headers that the Authorization Header is generated by the API Explorer.

cep-ep5-8

This completes all the work right from generating a Client ID, specifying Client Id details in the methods that we want to secure and then testing it out via the API explorer.

Note: Did you notice that we have not used the Client Id that we generated in the first step. This will become clear in the next episode where we shall write our JavaScript Web client and use the Client Id.

Project Source Code

I have updated the source code for the MyAPIProject2. You can download the entire source code over here.

Hope you liked this episode of the Google Cloud Endpoints tutorial. Stay tuned for more episodes, where we shall see how to invoke our secure API methods from a JavaScript client and an Android client.

About these ads

About rominirani

Google Developer Expert Cloud 2014. Harnessing the power of software by learning, teaching and developing simple solutions. I love learning about new technologies and teaching it to others.
This entry was posted in Cloud Computing, Google App Engine and tagged . Bookmark the permalink.

9 Responses to Google Cloud Endpoints Tutorial – Part 5

  1. Pingback: Google Cloud Endpoints Tutorial – Part 1 | iRomin

  2. Pingback: Google Cloud Endpoints Tutorial – Part 4 | iRomin

  3. Pingback: Google Cloud Endpoints Tutorial – Part 6 | iRomin

  4. Pingback: Google Cloud Endpoints Tutorial – Part 7 | iRomin

  5. Pingback: Google Cloud Endpoints Tips #3 : Understand Injected Types | iRomin

  6. Pingback: Google Cloud Endpoints Tutorial – Part 3 | iRomin

  7. Pingback: Google Cloud Endpoints Tutorial – Part 2 | iRomin

  8. Rijo says:

    Very Informative for Beginners.

  9. Pingback: Gradle Tutorial : Part 10 : Consuming Endpoints in Android Code | iRomin

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s