Designing JavaScript APIs

41
Designing JavaScript APIs Jonathan LeBlanc (@jcleblanc) Global Head of Developer Evangelism at PayPal

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

Page 1: Designing JavaScript APIs

Designing JavaScript APIs

Jonathan LeBlanc (@jcleblanc)

Global Head of Developer Evangelism at PayPal

Page 2: Designing JavaScript APIs

API? SDK?

Page 3: Designing JavaScript APIs

Automation?

Page 4: Designing JavaScript APIs

What JavaScript Can Feel Like

Page 5: Designing JavaScript APIs

JavaScript Challenges

Page 6: Designing JavaScript APIs

The Same-Origin Policy

Page 7: Designing JavaScript APIs

Keeping Private Keys Private

Page 8: Designing JavaScript APIs

Not Providing a Hacked Experience

Page 9: Designing JavaScript APIs

How Did We Used to Do It?

Page 10: Designing JavaScript APIs

Server-side Proxies

Page 11: Designing JavaScript APIs

Flash / iFrame Proxies

Page 12: Designing JavaScript APIs

Private Token Storage

Page 13: Designing JavaScript APIs

Securing Resources

Page 14: Designing JavaScript APIs

CORS Easy Access Control

OAuth 2

Tight Access Control

A Modern Approach

Page 15: Designing JavaScript APIs

OAuth 2 User Agent Flow

Page 16: Designing JavaScript APIs

Prepare the Redirect URIAuthorization Endpointclient_id response_type (token)scope redirect_uri

Browser RedirectRedirect URI

Redirect the User to Log In

Page 17: Designing JavaScript APIs

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

Page 18: Designing JavaScript APIs

Extract the Access Token

Fetch the Hash Modaccess_tokenrefresh_tokenexpires_in

Extract Access Token

Page 19: Designing JavaScript APIs

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

Page 20: Designing JavaScript APIs

Get Privileged API Resources

Set Request Headers + URIResource EndpointHeader: token type + access tokenHeader: accept data type

HTTPS Request

Page 21: Designing JavaScript APIs

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 }});

Page 22: Designing JavaScript APIs

CORS Easy Access Control

Page 23: Designing JavaScript APIs

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

Page 24: Designing JavaScript APIs

Can you use it?

http://caniuse.com/cors

Support: 79.42%Partial support: 8.84%

Total: 88.26%

Page 25: Designing JavaScript APIs

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?

Page 26: Designing JavaScript APIs

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?

Page 27: Designing JavaScript APIs

A Lil’ Bit O’ Automation

Page 28: Designing JavaScript APIs

Resource Identification

Resources must be manipulated via representations

Self descriptive messages

Hypermedia as the engine of application state

Uniform Interface Sub-Constraints

Page 29: Designing JavaScript APIs

Resource Identification

Resources must be manipulated via representations

Self descriptive messages

Hypermedia as the engine of application state

Uniform Interface Sub-Constraints

Page 30: Designing JavaScript APIs

HATEOAS

Page 31: Designing JavaScript APIs

How we Normally Consume APIs

Page 32: Designing JavaScript APIs

Using HATEOAS to Automate

Page 33: Designing JavaScript APIs

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

Page 34: Designing JavaScript APIs

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

Page 35: Designing JavaScript APIs

Open Path Library (what to do next)

Hierarchy of Requests

How do we Make it Work with JS?

Page 36: Designing JavaScript APIs

Object Chaining

Page 37: Designing JavaScript APIs

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

Page 38: Designing JavaScript APIs

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

Resources and Representations

Page 39: Designing JavaScript APIs

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

Page 40: Designing JavaScript APIs

Security needs to allow you to work the browser security model

Always assume statelessness

Build to allow your developers to automate complexities

In Summation

Page 41: Designing JavaScript APIs

Thanks! Questions?http://slideshare.com/jcleblanc

Jonathan LeBlanc (@jcleblanc)

Global Head of Developer Evangelism at PayPal