Upload
aiden-robertson
View
224
Download
0
Tags:
Embed Size (px)
Citation preview
Kirsten Jones, Technical Leader, Cisco Systems
Application Developers…Curious about using REST…Wanting help debugging the
system
Not REST API Architects (sorry!)
HTTP OverviewREST Web ServicesOAuth Authentication BasicsREST Debugging
HyperText Transfer ProtocolUsed for conversations between web
clients and serversMost of the internet uses HTTPSupports verbs for GET, PUT, POST,
DELETEQuery 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 formatParameters
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 URLEverything after the question mark,
delimited by ampersandshttp://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=EudJ2a15ql8832PCysQA0qchtuvGWMoA7rkp79VpIYAQ8-j42IO17LFudCYNMXm9l6SHcu3YgrGRCdrRCyM468xPZaOek4Pi-AXQ8eARqU1SGYx6y7_9LW-c3HHb-vs2; PREF=ID=994f8de0e8b39a5b:U=237805f1f710dc73:FF=0:TM=1336752507:LM=1336752509:S=W0Hha7x4czdXp51U
▪ Host: www.google.com
Google sends a response Headers:▪ Content-Length: 24716▪ Content-Encoding: gzip▪ Set-Cookie: NID=59=F48kbwfwOi-qCHJyrnMSUlDBVxK-
ZVKZpq5B5jttt_25IRN4lS-0rQcVttq-dnOIlQzafw1i4HPQAO0RpZ7NuC0WCKWta7SYoekx0--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: HTTPScoophttp://tuffcode.com/
Macintosh: Charles (supports SSL) http://www.charlesproxy.com/
Windows: Fiddlerhttp://www.fiddler2.com/fiddler2/
Unix (or Mac): Wireshark (X11)http://www.wireshark.org/
Request
Headers
Request/Response
Uses URL paths to define resourcesCreate, Read, Update, Delete
POST, GET, PUT, DELETEError Codes
HTTP Status CodesRequest parameters
Query parametersResponse types and configuration
Headers
Blog Info from TumblrGET (read)
http://api.tumblr.com/v2/blog/synedra.tumbler.com/info
Requires api_key sent as parameterhttp://api.tumblr.com/v2/blog/
synedra.tumblr.com/info?api_key=my_api_key
Headers
Request/Response
Status: 200Content:{"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 signatureAuthentication 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%2Fwww.linkedin.com%2Fin%2Fsynedra?oauth_body_hash=2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D&oauth_nonce=6283929&oauth_timestamp=1336775605&oauth_consumer_key=***KEY***&oauth_signature_method=HMAC-SHA1&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 oauthconsumer_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 oauthconsumer_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 generationurl = 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, headersLibrary out of sync with API
Try building the request using just the OAuth library
Find someone else’s code that worksHTTP Servers aren’t that smart
HTTP: Hypertext Transfer ProtocolREST: REpresentational State
TransferOAuth: Authentication