Demystifying Rest
Download
Report
Transcript Demystifying Rest
Kirsten Jones, Technical Leader, Cisco Systems
Application Developers
…Curious about using REST
…Wanting help debugging the system
Not REST API Architects (sorry!)
HTTP Overview
REST Web Services
OAuth Authentication Basics
REST Debugging
HyperText Transfer Protocol
Used for conversations between web clients
and servers
Most of the internet uses HTTP
Supports verbs for GET, PUT, POST, DELETE
Query parameter framework
Client sends a request
Method
URL
Headers
(sometimes) parameters
(sometimes) body
Server replies with a response
Content
Status
Headers
HTTP response codes for dummies.
50x: we fucked up.
40x: you fucked up.
30x: ask that dude over there.
20x: cool.
Props to @DanaDanger for this
Headers
Generally meta-information about the request
For instance: requesting an image in a specific
format
Parameters
Limit or describe how you want the resource
(searches, filters)
Defines the resource you’re requesting
Request (client)
Accept: Give me this kind of response. Here’s a
list in order of what I’m hoping you’ll send.
Accept: text/html,application/xhtml+xml,application/xml
Response (server)
Content-Type: This is the kind of response I’m
sending you.
Content-Type: text/html; charset=UTF-8
Part of the URL
Everything after the question mark, delimited
by ampersands
http://www.example.com/search_people?this
=that&foo=bar
Chrome browser sends a request to Google
Method: GET
URL: http://www.google.com
Headers:
▪
▪
▪
▪
▪
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3)
AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19
▪ Accept-Encoding: gzip,deflate,sdch
▪ Cookie: NID=59=EudJ2a15ql8832PCysQA0qchtuvGWMoA7rkp79VpIYAQ8j42IO17LFudCYNMXm9l6SHcu3YgrGRCdrRCyM468xPZaOek4PiAXQ8eARqU1SGYx6y7_9LW-c3HHb-vs2;
PREF=ID=994f8de0e8b39a5b:U=237805f1f710dc73:FF=0:TM=1336752507:LM=13
36752509:S=W0Hha7x4czdXp51U
▪ Host: www.google.com
Google sends a response
Headers:
▪ Content-Length: 24716
▪ Content-Encoding: gzip
▪ Set-Cookie: NID=59=F48kbwfwOi-qCHJyrnMSUlDBVxKZVKZpq5B5jttt_25IRN4lS-0rQcVttqdnOIlQzafw1i4HPQAO0RpZ7NuC0WCKWta7SYoekx0--YGf2zIFZ9VXIKS_UEaOH9iBe; expires=Sat, 10-Nov-2012 21:26:46 GMT; path=/;
domain=.google.com; HttpOnly
▪ Expires: -1
▪ Server: gws
▪ X-XSS-Protection: 1; mode=block
▪ Cache-Control: private, max-age=0
▪ X-Frame-Options: SAMEORIGIN
▪ Content-Type: text/html; charset=UTF-8
▪ Date: Fri, 11 May 2012 21:26:46 GMT
Content: A bunch of HTML
Status: 200
Some browsers provide tools to view HTTP
traffic
Great for understanding
what your browser is
doing
Tracking
programmatic
traffic requires a
separate tool
Macintosh: HTTPScoop
http://tuffcode.com/
Macintosh: Charles (supports SSL)
http://www.charlesproxy.com/
Windows: Fiddler
http://www.fiddler2.com/fiddler2/
Unix (or Mac): Wireshark (X11)
http://www.wireshark.org/
Request
Headers
Request/Response
Uses URL paths to define resources
Create, Read, Update, Delete
POST, GET, PUT, DELETE
Error Codes
HTTP Status Codes
Request parameters
Query parameters
Response types and configuration
Headers
Blog Info from Tumblr
GET (read)
http://api.tumblr.com/v2/blog/synedra.tumbl
er.com/info
Requires api_key sent as parameter
http://api.tumblr.com/v2/blog/synedra.tumbl
r.com/info?api_key=my_api_key
Headers
Request/Response
Status: 200
Content:
{"meta":
{"status":200, "msg":"OK” },
"response":{
"blog":{"title":"Untitled","posts":0,
"name":"synedra",
"url":"http:\/\/synedra.tumblr.com\/",
"updated":0,
"description":"","ask":false,"likes":0}}}
Used by many APIs
Each application gets a consumer key and secret
Authentication server handles authentication
Each user of an application gets a unique user
token and secret
Supports tracking of application/member use of
the API
Allows users to protect username/password
Industry standard – libraries for most
programming languages
REST web services call adds verification
signature to each request
Query parameters
Authorization header
Secrets are used to create signature
Authentication server checks signature to
verify that it was created using shared secrets
If authentication succeeds, request is
processed by API server
Signature is generated based on
URL
Parameters
Consumer key
User token
http://api.linkedin.com/v1/people/url=http%3A%2F%2Fw
ww.linkedin.com%2Fin%2Fsynedra?oauth_body_hash=2j
mj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D&oauth_nonce
=6283929&oauth_timestamp=1336775605&oauth_consu
mer_key=***KEY***&oauth_signature_method=HMACSHA1&oauth_version=1.0&oauth_token=***TOKEN***
&oauth_signature=CqHiZI6tI3pQGe5a0vVgoT0822A%3D
Request
Headers (nothing special)
Request/Response
Signature is generated based on
URL
Parameters
Consumer key
User token
URL is unchanged:
http://api.linkedin.com/v1/people/~/shares
Authorization header has oauth stuff:
OAuth realm="http://api.linkedin.com",
oauth_body_hash="JtgCKBurLIPLM4dXkn2E3lgrfI4%3D",
oauth_nonce="60723468", oauth_timestamp="1336776657",
oauth_consumer_key=”***KEY***",
oauth_signature_method="HMAC-SHA1", oauth_version="1.0",
oauth_token=”***TOKEN***",
oauth_signature="8iWVpIK3LhRbu8JPf2gzC1YxQy4%3D"
No authorization parameters
Authorization is in the header
Request/response works the same
Download the oauth2 package from github
No, it’s OAuth 1.0a, ignore the name
Quick walkthrough to understand process
(but this talk is not about OAuth)
import oauth2 as oauth
consumer_key
=
'xxxxxxxxxxxxxx'
consumer_secret =
'xxxxxxxxxxxxxx’
consumer = oauth.Consumer(consumer_key,
consumer_secret)
client = oauth.Client(consumer)
First step in OAuth: Get a request token for
this authorization session
OAuth library handles signing the request
import oauth2 as oauth
consumer_key
=
'xxxxxxxxxxxxxx'
consumer_secret =
'xxxxxxxxxxxxxx’
consumer = oauth.Consumer(consumer_key, consumer_secret)
client = oauth.Client(consumer)
resp, content = client.request(request_token_url, "POST")
request_token = dict(urlparse.parse_qsl(content))
Second step: Send the user to the server to
authorize your application
After the user authorizes your application,
the server returns a verification code for you
to use
print "Go to the following link in your browser:"
print "%s?oauth_token=%s" % (authorize_url,
request_token['oauth_token'])
accepted = 'n'
while accepted.lower() == 'n':
accepted = raw_input('Have you authorized me? (y/n) ')
oauth_verifier = raw_input('What is the PIN? ’)
Third step: Use the verifier and the request
token to get an access token
This is usually a long lived token
token = oauth.Token(request_token['oauth_token'],
request_token['oauth_token_secret'])
token.set_verifier(oauth_verifier)
client = oauth.Client(consumer, token)
resp, content = client.request(access_token_url, "POST")
access_token = dict(urlparse.parse_qsl(content))
Make an API call using the OAuth library
The library handles the signature generation
url = http://api.linkedin.com/v1/people/~
consumer = oauth.Consumer(
key=”XXXXX",
secret=”XXXXX")
token = oauth.Token(
key=”XXXXX",
secret=”XXXXX")
client = oauth.Client(consumer, token)
resp, content = client.request(url)
Use the documentation and resources
provided by the platform team
Consoles, IODocs, OAuth signature checkers
Use existing, tested libraries
Code defensively
401 authentication errors (signatures, tokens)
403 authorization errors (throttles,
permissions)
400 errors – parameters, headers
Library out of sync with API
Try building the request using just the OAuth
library
Find someone else’s code that works
HTTP Servers aren’t that smart
HTTP: Hypertext Transfer Protocol
REST: REpresentational State Transfer
OAuth: Authentication