secure restful api automation with javascript
DESCRIPTION
Pragmatic RESTful API principles, along with a solid consumption architecture, can allow for a great amount of automation in your program development. At the same time, securing the application can be extremely tricky from JavaScript. In this session we will explore several principles behind RESTful API design and consumption using JavaScript, many of the standards that were integrated in the redevelopment of the PayPal API architecture in the new RESTful APIs. We will cover many of these architecture standards, including: - Building in action automation using HATEOAS - OAuth 2 in the JavaScript model - The challenges behind secure resource consumption through JavaScriptTRANSCRIPT
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
CORS Easy Access Control
OAuth 2
Tight Access Control
OAuth 2 User Agent Flow
User Agent Flow: Redirect
Prepare the Redirect URIAuthorization Endpointclient_id response_type (token)scope redirect_uri
Browser RedirectRedirect 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 Modaccess_tokenrefresh_tokenexpires_in
Extract Access Token
User Agent Flow: Hash Mod
http://site.com/callback#access_token=rBEGu1FQr54AzqE3Q&refresh_token=rEBt51FZr54HayqE3V4a&expires_in=3600
var hash = document.location.hash;var match = hash.match(/access_token=(\w+)/);
Extracting the access token from the hash
User Agent Flow: Get Resources
Set Request Headers + URIResource EndpointHeader: token type + access tokenHeader: accept data type
HTTPS Request
User Agent Flow: Get Resources
$.ajax({ url: resource_uri, beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', 'OAuth ' + token); xhr.setRequestHeader('Accept', 'application/json'); }, success: function (response) { //use response object }});
Making an authorized request
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?
OPTIONS /v1/oauth2/token HTTP/1.1Origin: http://jcleblanc.comAccess-Control-Request-Method: PUTHost: api.sandbox.paypal.comAccept-Language: en-USConnection: keep-alive...
Site sends Origin header to server
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
curl -v -X GET https://api.sandbox.paypal.com/v1/payments/authorization/2DC87612EK520411B \
-H "Content-Type:application/json" \
-H "Authorization:Bearer ENxom5Fof1KqAffEsXtx1HTEK__KVdIsaCYF8C"
You make an API request
"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 StatelessSend 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
var paymentObj = getPreAuth(paymentID) //build pay
object.getNextAction() //next
HATEOAS link.processNext(); //process
action
The first request builds the action objectSubsequent calls manipulate the object
Security needs to allow you to work the browser security model
Always assume statelessness
Build to allow your developers to automate complexities
In Summation…
Thanks! Questions?http://www.slideshare.net/jcleblanc
Jonathan LeBlanc (@jcleblanc) Head of Developer Evangelism
PayPal North America