Using Web APIs
with OAuth 2.0
Nicolas Garnier @nivco
Alain Vongsouvanh
September 29, 2011
Nicolas Garnier @nivco
Alain Vongsouvanh
September 29, 2011
Twitter: @nivco
Google+: plus.nicolasgarnier.com
POST /urlshortener/v1/url HTTP/1.1
Host: www.googleapis.com
Content-Type: application/json
{
"longUrl": "http://www.verylongurl.com/"
}
HTTP/1.1 200 OK
{
"kind": "urlshortener#url",
"id": "http://goo.gl/fbsS",
"longUrl": "http://www.verylongurl.com/"
}
cURL is a command line tool. It is awsome.
Everybody should know how to use it :)
curl -H 'Content-Type: application/json' \
-d '{"longUrl": "http://www.verylongurl.com/"}' \
"https://www.googleapis.com/urlshortener/v1/url"
{
"kind": "urlshortener#url",
"id": "http://goo.gl/fbsS",
"longUrl": "http://www.verylongurl.com/"
}
We are using the URL Fetch service:
HTTPRequest req = new HTTPRequest(
new URL("https://www.googleapis.com/urlshortener/v1/url"),
HTTPMethod.POST);
req.addHeader(
new HTTPHeader("Content-Type", "application/json"));
req.setPayload(
new String("{\"longUrl\": \"http://www.verylongurl.com/\"}").getBytes());
HTTPResponse res = URLFetchServiceFactory.getURLFetchService().fetch(req);
String response = new String(res.getContent());
System.out.println(response);
POST /urlshortener/v1/url?key=xyz HTTP/1.1
Host: www.googleapis.com
Content-Type: application/json
{
"longUrl": "http://www.verylongurl.com/"
}
HTTP/1.1 200 OK
{
"kind": "urlshortener#url",
"id": "http://goo.gl/fbsS",
"longUrl": "http://www.verylongurl.com/"
}
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | Authorization Grant & +---------------+
| |--(C)--- Client Credentials -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
web-apis-slides.appspot.com
REDIRECT https://accounts.google.com/o/oauth2/auth?
client_id=685953454903.apps.googleusercontent.com&
redirect_uri=https://appid.appspot.com/back&
scope=https://www.googleapis.com/auth/urlshortener&
response_type=code
web-apis-slides.appspot.com
if the User approved access:
https://appid.appspot.com/back?code=4/P7q8W92a-oMsCeLvIaQm6bTrgtp7
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com code=4/P7q8W92a-oMsCeLvIaQm6bTrgtp7& client_id=685953454903.apps.googleusercontent.com& client_secret=Au4-Kcj1TPv0ycmNbjNV_esF& redirect_uri=https://www.example.com/back& grant_type=authorization_code
HTTP/1.1 200 OK
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"refresh_token": "1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ"
}
GET /urlshortener/v1/url/history HTTP/1.1 Host: www.googleapis.com Authorization: OAuth 1/fFAGRNJru1FTz70BzhT3Zg
HTTP/1.1 200 OK
{
"totalItems": 72,
"itemsPerPage": 30,
"nextPageToken": "2011-06-15T06:59:22.584+00:00",
"items": [
{
"kind": "urlshortener#url",
"id": "http://goo.gl/fbsS",
"longUrl": "http://www.verylongurl.com/",
"status": "OK",
"created": "2010-12-13T07:22:55.000+00:00",
} /* , ... */
]
}
Get the jars on project hosting: google-api-java-client
The redirection to the authorization page:
public class RedirectToAuthServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Redirecting user to the auth page for URL Shortner
resp.sendRedirect(
new GoogleAuthorizationRequestUrl("685953454903.apps.googleusercontent.com",
"http://myapp.appspot.com/printShortenerHistory",
"https://www.googleapis.com/auth/urlshortener").build());
}
}
The OAuth code callback:
public class PrintShortenerHistoryServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Reading the code from URL
String code = req.getParameterValues("code")[0];
// We need an App Engine sepcific HTTP Transport and a JSON parser
HttpTransport transport = new UrlFetchTransport();
JacksonFactory jsonFactory = new JacksonFactory();
// Exchange code for access and refresh tokens
AccessTokenResponse tokens = new GoogleAuthorizationCodeGrant(httpTransport,
jsonFactory, "685953454903.apps.googleusercontent.com", "Au4-Kcj1TPv0ycmNbjNV_esF",
code, "http://myapp.appspot.com/printShortnerHistory").execute();
// TODO: now use the API
}
}
Call to the API and parsing results:
// This handles the OAuth 2 stuff for us
GoogleAccessProtectedResource gapr = new GoogleAccessProtectedResource(
tokens.accessToken, transport, jsonFactory, "685953454903.apps.googleusercontent.com",
"Au4-Kcj1TPv0ycmNbjNV_esF", tokens.refreshToken);
// A service to use the URL Shortner
Urlshortener service = new Urlshortener(transport, gapr, jsonFactory);
// Getting the URL Shortner history of the user
UrlHistory urls = service.url.list().execute();
// Writing the tasks titles to the output
resp.setContentType("text/plain");
for (Url url : urls.getItems()) {
resp.getWriter().append(url.getLongUrl() + " -> " + url.getId() + "\n");
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" ...>
...
<servlet>
<servlet-name>PrintShortnerHistoryServlet</servlet-name>
<servlet-class>com.google.oauthsample.PrintShortnerHistoryServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrintShortnerHistoryServlet</servlet-name>
<url-pattern>/printShortnerHistory</url-pattern>
</servlet-mapping>
</web-app>
| Resource | URI | GET | PUT | POST | DELETE |
|---|---|---|---|---|---|
| Collection | /resources/ | List | Replace | Create | Delete |
| Element | /resources/id | Retrieve | Update | Create | Delete |
POST /buzz/v1/activities/@me/@self HTTP/1.1
Host: www.googleapis.com
Authorization: 1/fFAGRNJru1FTz70BzhT3Zg
Content-Type: application/json
{
"data": {
"object": {
"type": "note",
"content": "Is anybody listening ?"
}
}
}
GET /buzz/v1/people/@me/@groups/@followers HTTP/1.1 Host: www.googleapis.com
HTTP/1.1 200 OK
{
"data": {
"kind": "buzz#peopleFeed",
"entry": []
}
}
REDIRECT https://accounts.google.com/o/oauth2/auth? client_id=685953454903.apps.googleusercontent.com& redirect_uri=https://appid.appspot.com/back& scope=https://www.googleapis.com/auth/urlshortener%20\ https://www.googleapis.com/auth/buzz& response_type=code
web-apis-slides.appspot.com
if the User approved access:
https://appid.appspot.com/back?code=4/P7q8W92a-oMsCeLvIaQm6bTrgtp7
It will Buzz the Title of the URL along with its short link
web-apis-slides.appspot.comThe redirection to the authorization page:
public class RedirectToAuthServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Redirecting user to the auth page for URL Shortner
GoogleAuthorizationRequestUrl url = new GoogleAuthorizationRequestUrl(
"685953454903.apps.googleusercontent.com",
"http://myapp.appspot.com/buzzShortUrl",
"https://www.googleapis.com/auth/urlshortener " +
"https://www.googleapis.com/auth/buzz");
url.state = req.getParameterValues("longurl")[0];
resp.sendRedirect(url.build());
}
}
Get the short URL and Buzz it:
// Skipped... Get the auth code, exchange it for tokens etc...
// Get the longURL from the request parameter
String longUrl = req.getParameterValues("state")[0];
// Creating a new Short URL
Urlshortener usService = new Urlshortener(transport, gapr, jsonFactory);
Url newLongUrl = new Url();
newLongUrl.setLongUrl(longUrl);
Url url = usService.url.insert(newLongUrl).execute();
// Get the page title
String html = new String(URLFetchServiceFactory.getURLFetchService().fetch(
new URL(longUrl)).getContent());
String pageTitle = html.substring(html.indexOf("<title>") + 7, html.indexOf("</title>"));
// Buzz the short URL
Buzz bService = new Buzz(transport, gapr, jsonFactory);
Activity activity = new Activity();
ActivityObject ao = new ActivityObject();
ao.setType("note");
ao.setContent(pageTitle + ": " + url.getId());
activity.setBuzzObject(ao);
activity = bService.activities.insert("@me", activity).execute();
// Redirect user to the Buzz post
resp.sendRedirect(activity.getLinks().get("alternate"));
GET /demo?url=http://webexpo.cz/praha2011/...
Feedback on Twitter: @nivco
Google+: plus.nicolasgarnier.com