Designing JavaScript APIs

Post on 28-Jan-2015

117 views 0 download

Tags:

description

API creation within JavaScript introduces a whole new array of security and request issues that traditional APIs never encounter. In this session we’ll explore several principles behind JavaScript API design and architecture, including OAuth 2 in the JavaScript model, Cross-Origin Resource Sharing for browser security constraints, building action automation with HATEOAS, and challenges behind secure resource consumption through JavaScript

Transcript of Designing JavaScript APIs

Designing JavaScript APIs

Jonathan LeBlanc (@jcleblanc)

Global Head of Developer Evangelism at PayPal

API? SDK?

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 Resources

CORS Easy Access Control

OAuth 2

Tight Access Control

A Modern Approach

OAuth 2 User Agent Flow

Prepare the Redirect URIAuthorization Endpointclient_id response_type (token)scope redirect_uri

Browser RedirectRedirect URI

Redirect the User to Log In

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: Redirect

Extract the Access Token

Fetch the Hash Modaccess_tokenrefresh_tokenexpires_in

Extract Access Token

User Agent Flow: Hash Mod

Extract the Access Token from the Hash

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+)/);

Get Privileged API Resources

Set Request Headers + URIResource EndpointHeader: token type + access tokenHeader: 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

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

Cross Origin Issues and Options

Can you use it?

http://caniuse.com/cors

Support: 79.42%Partial support: 8.84%

Total: 88.26%

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

How Does it Work?

A Lil’ Bit O’ Automation

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

Uniform Interface Sub-Constraints

HATEOAS

How we Normally Consume APIs

Using HATEOAS to Automate

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

How HATEOAS Works

"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” }]

Open Path Library (what to do next)

Hierarchy of Requests

How do we Make it Work with JS?

Object Chaining

Send complete object to only make 1 request

{ "id": "PAY-17S8410768582940NKEE66EQ", "create_time": "2013-01-31T04:12:02Z", "update_time": "2013-01-31T04:12:04Z", "state": "approved", "intent": "sale", "payer": {...}, "transactions": [{...}], "links": [{...}] }

The System Should be Stateless

Manipulate a concept (e.g. payment) with the intended state

Resources and Representations

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

Chaining Actions

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://slideshare.com/jcleblanc

Jonathan LeBlanc (@jcleblanc)

Global Head of Developer Evangelism at PayPal