Secure RESTful API Automation With JavaScript Jonathan LeBlanc (@jcleblanc) Head of Developer Evangelism PayPal North America
Automation?
What JavaScript Can Feel Like
JavaScript Challenges
The Same-Origin Policy
Keeping Private Keys Private
Not Providing a Hacked Experience
How Did We Used to Do It?
Server-side Proxies
Flash / iFrame Proxies
Private Token Storage
Securing Content Negotiation
A Modern Approach OAuth 2 Tight Access Control CORS Easy Access Control
OAuth 2 User Agent Flow
User Agent Flow: Redirect Prepare the Redirect URI Authorization Endpoint client_id response_type (token) scope redirect_uri Browser Redirect Redirect URI
User Agent Flow: Redirect Building the redirect link var auth_uri = auth_endpoint + "?response_type=token" + "&client_id=" + client_id + "&scope=profile" + "&redirect_uri=" + window.location; $("#auth_btn").attr("href", auth_uri);
User Agent Flow: Hash Mod Fetch the Hash Mod access_token refresh_token expires_in Extract Access Token
User Agent Flow: Hash Mod Extracting the access token from the hash http://site.com/callback#access_token=rBEGu1FQr5 4AzqE3Q&refresh_token=rEBt51FZr54HayqE3V4a& expires_in=3600 var hash = document.location.hash; var match = hash.match(/access_token=(w+)/);
User Agent Flow: Get Resources Set Request Headers + URI Resource Endpoint Header: token type + access token Header: accept data type HTTPS Request
User Agent Flow: Get Resources Making an authorized request $.ajax({ url: resource_uri, beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', 'OAuth ' + token); xhr.setRequestHeader('Accept', 'application/json'); }, success: function (response) { //use response object } });
CORS Easy Access Control
Cross Origin Issues and Options Access to other domains / subdomains is restricted (same origin policy) JSONP to request resources across domains Only supports HTTP GET requests Cross-origin resource sharing (CORS) Supports additional range of HTTP requests
Can you use it? http://caniuse.com/cors
How Does it Work? Site sends Origin header to server OPTIONS /v1/oauth2/token HTTP/1.1 Origin: http://jcleblanc.com Access-Control-Request-Method: PUT Host: api.sandbox.paypal.com Accept-Language: en-US Connection: keep-alive ...
How Does it Work? Server responds with matching Access-Control-Allow-Origin header Access-Control-Allow-Origin: http://jcleblanc.com Access-Control-Allow-Methods: GET, POST, PUT Content-Type: text/html; charset=utf-8
A Lil’ Bit O’ Automation
Uniform Interface Sub-Constraints Resource Identification Resources must be manipulated via representations Self descriptive messages Hypermedia as the engine of application state
Uniform Interface Sub-Constraints Resource Identification Resources must be manipulated via representations Self descriptive messages Hypermedia as the engine of application state
HATEOAS
How we Normally Consume APIs
Using HATEOAS to Automate
How HATEOAS Works You make an API request curl -v -X GET https://api.sandbox.paypal.com/v1/payments/authoriz ation/2DC87612EK520411B -H "Content-Type:application/json" -H "Authorization:Bearer ENxom5Fof1KqAffEsXtx1HTEK__KVdIsaCYF8C"
"links": [ { "href":"https://api.sandbox.paypal.com/v1/payments/ authorization/6H149011U8307001M", "rel":"self", "method":"GET" },{ "href":"https://api.sandbox.paypal.com/v1/payments/ authorization/6H149011U8307001M/capture", "rel":"capture", "method":"POST" },{ "href":"https://api.sandbox.paypal.com/v1/payments/ authorization/6H149011U8307001M/void", "rel":"void", "method":"POST" } ]
Object Chaining
Interactions Should be Stateless Send enough detail to not have to make another request to the API { "id": "PAY-17S8410768582940NKEE66EQ", "create_time": "2013-01-31T04:12:02Z", "update_time": "2013-01-31T04:12:04Z", "state": "approved", "intent": "sale", "payer": {...}, "transactions": [{...}], "links": [{...}] }
Resources and Representations Manipulate a concept (e.g. payment) with the intended state
Chaining Actions The first request builds the action object Subsequent calls manipulate the object var paymentObj = getPreAuth(paymentID) .getNextAction() .processNext(); //build pay object //next HATEOAS link //process action
In Summation… Security needs to allow you to work the browser security model Always assume statelessness Build to allow your developers to automate complexities
Thanks! Questions? http://www.slideshare.net/jcleblanc Jonathan LeBlanc (@jcleblanc) Head of Developer Evangelism PayPal North America

Secure RESTful API Automation With JavaScript

Editor's Notes

  • #7 Keeping private keys private
  • #23 JSONP can cause XSS issues where the external site is compromised, CORS allows websites to manually parse responses to ensure security
  • #26 Behind the server scene, the server looks up the application in their records to verify that the application matches what is on file against the application location making the request
  • #30 Hypermedia as the engine of application state
  • #35 Resources must be manipulated via representations. This goes back to the stateless principles
  • #38 REST principle of using objects applied to chaining multiple objects together