SlideShare a Scribd company logo
1 of 31
Download to read offline
Hi. I’m Matthew.
@mixonic
httP://madhatted.com
matt.beale@madhatted.com
201 Created
We build õ-age apps with Ember.js. We take
teams from £ to • in no time flat.
http://bit.ly/ember-toronto-edge
authentication
The Goal
•Auth against multiple 3rd party services
•Don’t be reloading the page
•keep the complexity off the server
One page, no reload
Sign In
Auth at Windows Live
Signed In!
OAuth2
•access to resources via tokens
•Several token types
•a different flow for each type
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
resource owner password credentials grant
Do not use this
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
Authorization code grant
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
implicit grant
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
implicit grant
browser
Facebook Auth
website server
website
User
Facebook connect
Implicit Grant supported by
•facebook (behind sdk)
•google
•soundcloud
•box.net
•windows live
!
•& more
Building it!
Abstractions
•session manager (controller)
•Oauth adapter
•live, FB specific adapters
•popup manager
6 <div {{bind-attr class=":sign-in-menu isOpen:open:closed"}}>
7 <a class="sign-in-button facebook" href="#" {{action "selectService" "facebook"}}>
8 Sign In with Facebook
9 </a>
10 <a class="sign-in-button windows" href="#" {{action "selectService" "live"}}>
11 Sign In with Windows Live
12 </a>
13 <div class="mobile-show menu-footer subheader">
14 {{link-to 'Leaderboard' 'leaderboard'}}
15 {{link-to 'About' 'map.about'}}
16 </div>
17 </div>
36 signIn: function(service){
37 var session = this.get('session'),
38 route = this;
39 session.open(service)
40 .then(function(){
41 if (route.router.isActive('map')) {
42 route.disconnectOutlet({
43 outlet: 'prompt',
44 parentView: 'map/neighborhood'
45 });
46 }
47 var lastTransition = session.get('afterRedirect');
48 if (lastTransition) {
49 lastTransition.retry();
50 } else if (route.router.isActive('sign_in')) {
51 route.transitionTo('');
52 }
53 }).catch(Ember.Logger.error);
54 },
61 Ember.Application.initializer({
62 name: 'authentication',
63 initialize: function(container, app){
. . .
65 import Session from 'appkit/controllers/session';
66 container.register('session:main', Session);
67 app.inject('controller', 'session', 'session:main');
68 app.inject('route', 'session', 'session:main');
. . .
95 });
inject session
9 open: function(credentials){
10 var session = this;
11 session.set('isAuthenticating', true);
12
13 return this.get('adapter').open(credentials, this)
14 .then(function(user){
15 session.setProperties({
16 isAuthenticated: true,
17 currentUser: user
18 });
19 return user;
20 }).catch(function(err){
21 if (err === 'canceled') {
22 return; // no-op
23 } else {
24 return Ember.RSVP.reject(err);
25 }
26 }).finally(function(){
27 session.set('isAuthenticating', false);
28 });
29 },
opening a session
61 Ember.Application.initializer({
62 name: 'authentication',
63 initialize: function(container, app){
. . .
70 import Auth from 'appkit/models/auth';
71 container.register('session:adapter', Auth);
72 app.inject('session:adapter', 'store', 'store:main');
73 app.inject('session:main', 'adapter', 'session:adapter');
. . .
95 });
Inject Auth adapter
50 // returns a promise that resolves to a user
51 open: function(serviceName){
52 var auth = this;
53 var authService = this.container.lookup('auth:' + serviceName);
54
55 if (!authService) {
56 return Ember.RSVP.reject('unrecognized service auth:' +
57 serviceName);
58 } else {
59 return authService.open()
60 .then( function(serviceData) {
61 // create a session
62 var sessionData = {
63 authData: {
64 name: serviceData.name,
65 id: serviceData.id,
66 accessToken: serviceData.accessToken
67 }
68 };
69 var session = auth.get('store').createRecord('session',
70 sessionData);
71 return session.save();
72 }).then( function(session){
73 auth.set('authToken', session.get('id'));
74
75 return session.get('user');
76 });
77 }
78 },
open an auth attempt
25 var LiveAuthService = Ember.Object.extend({
26 open: function(){
27 return this.signIn()
28 .then( this.normalizeServiceData );
29 },
30
31 signIn: function(){
32 var url = createAuthUrl();
33 return this.get('popup').
34 open(url, {width: 500, height: 510 });
35 },
36
37 normalizeServiceData: function(accessToken){
38 return {
39 name: 'live',
40 accessToken: accessToken
41 };
42 }
43 });
open windows live auth attempt
38 App.initializer({
39 name: 'Register Services',
40 initialize: function(container, app) {
41 registerServices(container);
42
43 // force creation of FacebookAuthService (to load the FB global)
44 container.lookup('auth:facebook');
45
46 app.inject('auth', 'popup', 'popups:authenticate');
47 }
48 });
Inject popup service
65 open: function(url, options) {
66 this.closeExistingWindow();
67 this.rejectExistingDeferred('canceled');
68 var deferred = this.generateNewDeferred();
69 var defaultedOptions = this.applyDefaultOptions(options);
70 this.popup = window.open(
71 url, 'authentication', parameterizeOptions(defaultedOptions)
72 );
73
74 if (this.popup) {
75 this.popup.focus();
76 $(window).on('message', this.boundMessageHandler);
77 } else {
78 this.rejectExistingDeferred('failed to open popup');
79 }
80
81 return deferred.promise;
82 },
30 createBoundMessageHandler: function(){
31 this.boundMessageHandler = function(event){
32 var matches, message = event.originalEvent.data;
33 if (!message || !(matches = message.match(/^setAccessToken:(.*)/))){
34 return;
35 }
36
37 if (matches[1]){
38 Ember.run(this, function(){
39 this.closeExistingWindow();
40 this.resolveExistingDeferred(matches[1]);
41 });
42 }
43 }.bind(this);
44 }.on('init'),
Listen for messages from the popup
Upon load, look for tokens
61 Ember.Application.initializer({
62 name: 'authentication',
63 initialize: function(container, app){
. . .
75 // Kind of feels like the in-popup logic should be elsewhere
76 var auth = container.lookup('session:adapter');
77 var token = auth.readAccessToken();
78 if (token && window.opener) {
79 // Don't go forward, we are just a popup with an accessToken
80 app.deferReadiness();
81 window.opener.postMessage(
82 'setAccessToken:'+token,
83 Overherd.settings.origin
84 );
85 }
. . .
94 }
95 });
Upon load, look for tokens
99 readAccessToken: function(){
100 var accessToken, match,
101 regex = /access_token=([^&]*)/,
102 hash = window.location.hash;
103
104 if (window.location.hash){
105 hash = window.location.hash;
106 if (match = hash.match(regex)) {
107 return match[1];
108 }
109 }
110 }
promises complete!
Other ideas
•localstorage for auth tokens
•how to recognize a cancelled sign in?
•we still check the token is valid
server-side
Try it
HereHere.co
Thanks!
@mixonic
httP://madhatted.com
matt.beale@madhatted.com

More Related Content

What's hot

What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020
What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020
What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020Matt Raible
 
Frontends w ithout javascript
Frontends w ithout javascriptFrontends w ithout javascript
Frontends w ithout javascriptStephen Lorello
 
Stateless Auth using OAuth2 & JWT
Stateless Auth using OAuth2 & JWTStateless Auth using OAuth2 & JWT
Stateless Auth using OAuth2 & JWTGaurav Roy
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web developmentJohannes Brodwall
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and LibraryKenji Otsuka
 
Using OAuth with PHP
Using OAuth with PHPUsing OAuth with PHP
Using OAuth with PHPDavid Ingram
 
Rest Security with JAX-RS
Rest Security with JAX-RSRest Security with JAX-RS
Rest Security with JAX-RSFrank Kim
 
The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...
The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...
The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...Codemotion
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4DEVCON
 
Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4DEVCON
 
Desenvolvimento web com Ruby on Rails (extras)
Desenvolvimento web com Ruby on Rails (extras)Desenvolvimento web com Ruby on Rails (extras)
Desenvolvimento web com Ruby on Rails (extras)Joao Lucas Santana
 
201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbrokerFIWARE
 
FIWARE Developers Week_ Introduction to Managing Context Information at Large...
FIWARE Developers Week_ Introduction to Managing Context Information at Large...FIWARE Developers Week_ Introduction to Managing Context Information at Large...
FIWARE Developers Week_ Introduction to Managing Context Information at Large...FIWARE
 
Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013
Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013
Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013Aaron Parecki
 
Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2Jonathan LeBlanc
 

What's hot (20)

OAuth 2.0
OAuth 2.0OAuth 2.0
OAuth 2.0
 
What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020
What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020
What the Heck is OAuth and OIDC - Denver Developer Identity Workshop 2020
 
Demystifying OAuth 2.0
Demystifying OAuth 2.0Demystifying OAuth 2.0
Demystifying OAuth 2.0
 
OAuth 2 Presentation
OAuth 2 PresentationOAuth 2 Presentation
OAuth 2 Presentation
 
Frontends w ithout javascript
Frontends w ithout javascriptFrontends w ithout javascript
Frontends w ithout javascript
 
Stateless Auth using OAuth2 & JWT
Stateless Auth using OAuth2 & JWTStateless Auth using OAuth2 & JWT
Stateless Auth using OAuth2 & JWT
 
Android ax app wcf
Android ax app wcfAndroid ax app wcf
Android ax app wcf
 
Android+ax+app+wcf
Android+ax+app+wcfAndroid+ax+app+wcf
Android+ax+app+wcf
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
 
OAuth 2.0 and Library
OAuth 2.0 and LibraryOAuth 2.0 and Library
OAuth 2.0 and Library
 
Using OAuth with PHP
Using OAuth with PHPUsing OAuth with PHP
Using OAuth with PHP
 
Rest Security with JAX-RS
Rest Security with JAX-RSRest Security with JAX-RS
Rest Security with JAX-RS
 
The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...
The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...
The Web Components interoperability challenge - Horacio Gonzalez - Codemotion...
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4
 
Desenvolvimento web com Ruby on Rails (extras)
Desenvolvimento web com Ruby on Rails (extras)Desenvolvimento web com Ruby on Rails (extras)
Desenvolvimento web com Ruby on Rails (extras)
 
201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker
 
FIWARE Developers Week_ Introduction to Managing Context Information at Large...
FIWARE Developers Week_ Introduction to Managing Context Information at Large...FIWARE Developers Week_ Introduction to Managing Context Information at Large...
FIWARE Developers Week_ Introduction to Managing Context Information at Large...
 
Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013
Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013
Using ArcGIS with OAuth 2.0 - Esri DevSummit Dubai 2013
 
Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2
 

Similar to Client-side Auth with Ember.js

Distributed Identities with OpenID
Distributed Identities with OpenIDDistributed Identities with OpenID
Distributed Identities with OpenIDBastian Hofmann
 
Distributed Identities with OpenID
Distributed Identities with OpenIDDistributed Identities with OpenID
Distributed Identities with OpenIDBastian Hofmann
 
How to create social apps for millions of users
How to create social apps for millions of users How to create social apps for millions of users
How to create social apps for millions of users Bastian Hofmann
 
Serverless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applicationsServerless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applicationsLoiane Groner
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsBastian Hofmann
 
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...Maarten Balliauw
 
Crossing the Boundaries of Web Applications with OpenSocial
Crossing the Boundaries of Web Applications with OpenSocialCrossing the Boundaries of Web Applications with OpenSocial
Crossing the Boundaries of Web Applications with OpenSocialBastian Hofmann
 
Passwords suck, but centralized proprietary services are not the answer
Passwords suck, but centralized proprietary services are not the answerPasswords suck, but centralized proprietary services are not the answer
Passwords suck, but centralized proprietary services are not the answerFrancois Marier
 
OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...
OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...
OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...Maarten Balliauw
 
How to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health AppHow to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health AppBen Adida
 
Persona: in your browsers, killing your passwords
Persona: in your browsers, killing your passwordsPersona: in your browsers, killing your passwords
Persona: in your browsers, killing your passwordsFrancois Marier
 
使用 Passkeys 打造無密碼驗證服務
使用 Passkeys 打造無密碼驗證服務使用 Passkeys 打造無密碼驗證服務
使用 Passkeys 打造無密碼驗證服務升煌 黃
 
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control
OAuth-as-a-serviceusing ASP.NET Web API and Windows Azure Access ControlOAuth-as-a-serviceusing ASP.NET Web API and Windows Azure Access Control
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access ControlMaarten Balliauw
 
OSCamp #4 on Foreman | CLI tools with Foreman by Martin Bačovský
OSCamp #4 on Foreman | CLI tools with Foreman by Martin BačovskýOSCamp #4 on Foreman | CLI tools with Foreman by Martin Bačovský
OSCamp #4 on Foreman | CLI tools with Foreman by Martin BačovskýNETWAYS
 
international PHP2011_Bastian Hofmann_Mashing up java script
international PHP2011_Bastian Hofmann_Mashing up java scriptinternational PHP2011_Bastian Hofmann_Mashing up java script
international PHP2011_Bastian Hofmann_Mashing up java scriptsmueller_sandsmedia
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSChih-Hsuan Kuo
 

Similar to Client-side Auth with Ember.js (20)

Distributed Identities with OpenID
Distributed Identities with OpenIDDistributed Identities with OpenID
Distributed Identities with OpenID
 
Distributed Identities with OpenID
Distributed Identities with OpenIDDistributed Identities with OpenID
Distributed Identities with OpenID
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 
How to create social apps for millions of users
How to create social apps for millions of users How to create social apps for millions of users
How to create social apps for millions of users
 
Serverless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applicationsServerless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applications
 
Oauth
OauthOauth
Oauth
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control - W...
 
Crossing the Boundaries of Web Applications with OpenSocial
Crossing the Boundaries of Web Applications with OpenSocialCrossing the Boundaries of Web Applications with OpenSocial
Crossing the Boundaries of Web Applications with OpenSocial
 
Passwords suck, but centralized proprietary services are not the answer
Passwords suck, but centralized proprietary services are not the answerPasswords suck, but centralized proprietary services are not the answer
Passwords suck, but centralized proprietary services are not the answer
 
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access ControlOAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control
 
OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...
OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...
OAuth-as-a-service - using ASP.NET Web API and Windows Azure Access Control -...
 
How to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health AppHow to Build an Indivo X Personal Health App
How to Build an Indivo X Personal Health App
 
Persona: in your browsers, killing your passwords
Persona: in your browsers, killing your passwordsPersona: in your browsers, killing your passwords
Persona: in your browsers, killing your passwords
 
使用 Passkeys 打造無密碼驗證服務
使用 Passkeys 打造無密碼驗證服務使用 Passkeys 打造無密碼驗證服務
使用 Passkeys 打造無密碼驗證服務
 
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control
OAuth-as-a-serviceusing ASP.NET Web API and Windows Azure Access ControlOAuth-as-a-serviceusing ASP.NET Web API and Windows Azure Access Control
OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control
 
OSCamp #4 on Foreman | CLI tools with Foreman by Martin Bačovský
OSCamp #4 on Foreman | CLI tools with Foreman by Martin BačovskýOSCamp #4 on Foreman | CLI tools with Foreman by Martin Bačovský
OSCamp #4 on Foreman | CLI tools with Foreman by Martin Bačovský
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 
international PHP2011_Bastian Hofmann_Mashing up java script
international PHP2011_Bastian Hofmann_Mashing up java scriptinternational PHP2011_Bastian Hofmann_Mashing up java script
international PHP2011_Bastian Hofmann_Mashing up java script
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OS
 

More from Matthew Beale

Ember.js Module Loading
Ember.js Module LoadingEmber.js Module Loading
Ember.js Module LoadingMatthew Beale
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017Matthew Beale
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component PatternsMatthew Beale
 
Ember Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkEmber Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkMatthew Beale
 
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)Matthew Beale
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
New Component Patterns in Ember.js
New Component Patterns in Ember.jsNew Component Patterns in Ember.js
New Component Patterns in Ember.jsMatthew Beale
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector emberMatthew Beale
 
Testing Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyTesting Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyMatthew Beale
 
Parse Apps with Ember.js
Parse Apps with Ember.jsParse Apps with Ember.js
Parse Apps with Ember.jsMatthew Beale
 
Snappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsSnappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsMatthew Beale
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.jsMatthew Beale
 
Complex Architectures in Ember
Complex Architectures in EmberComplex Architectures in Ember
Complex Architectures in EmberMatthew Beale
 
Ember and containers
Ember and containersEmber and containers
Ember and containersMatthew Beale
 

More from Matthew Beale (15)

Ember.js Module Loading
Ember.js Module LoadingEmber.js Module Loading
Ember.js Module Loading
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component Patterns
 
Ember Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkEmber Community 2016 - Be the Bark
Ember Community 2016 - Be the Bark
 
Attribute actions
Attribute actionsAttribute actions
Attribute actions
 
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
New Component Patterns in Ember.js
New Component Patterns in Ember.jsNew Component Patterns in Ember.js
New Component Patterns in Ember.js
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector ember
 
Testing Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyTesting Ember Apps: Managing Dependency
Testing Ember Apps: Managing Dependency
 
Parse Apps with Ember.js
Parse Apps with Ember.jsParse Apps with Ember.js
Parse Apps with Ember.js
 
Snappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsSnappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember Apps
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Complex Architectures in Ember
Complex Architectures in EmberComplex Architectures in Ember
Complex Architectures in Ember
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 

Recently uploaded

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 

Recently uploaded (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 

Client-side Auth with Ember.js

  • 3. 201 Created We build õ-age apps with Ember.js. We take teams from £ to • in no time flat.
  • 6. The Goal •Auth against multiple 3rd party services •Don’t be reloading the page •keep the complexity off the server
  • 7. One page, no reload Sign In Auth at Windows Live Signed In!
  • 8. OAuth2 •access to resources via tokens •Several token types •a different flow for each type
  • 9. +----------+ | Resource | | Owner | | | +----------+ v | Resource Owner (A) Password Credentials | v +---------+ +---------------+ | |>--(B)---- Resource Owner ------->| | | | Password Credentials | Authorization | | Client | | Server | | |<--(C)---- Access Token ---------<| | | | (w/ Optional Refresh Token) | | +---------+ +---------------+ resource owner password credentials grant Do not use this
  • 10. +----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI ---->| | | User- | | Authorization | | Agent -+----(B)-- User authenticates --->| Server | | | | | | -+----(C)-- Authorization Code ---<| | +-|----|---+ +---------------+ | | ^ v (A) (C) | | | | | | ^ v | | +---------+ | | | |>---(D)-- Authorization Code ---------' | | Client | & Redirection URI | | | | | |<---(E)----- Access Token -------------------' +---------+ (w/ Optional Refresh Token) Authorization code grant
  • 11. +----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI --->| | | User- | | Authorization | | Agent -|----(B)-- User authenticates -->| Server | | | | | | |<---(C)--- Redirection URI ----<| | | | with Access Token +---------------+ | | in Fragment | | +---------------+ | |----(D)--- Redirection URI ---->| Web-Hosted | | | without Fragment | Client | | | | Resource | | (F) |<---(E)------- Script ---------<| | | | +---------------+ +-|--------+ | | (A) (G) Access Token | | ^ v +---------+ | | | Client | | | +---------+ implicit grant
  • 12. +----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI --->| | | User- | | Authorization | | Agent -|----(B)-- User authenticates -->| Server | | | | | | |<---(C)--- Redirection URI ----<| | | | with Access Token +---------------+ | | in Fragment | | +---------------+ | |----(D)--- Redirection URI ---->| Web-Hosted | | | without Fragment | Client | | | | Resource | | (F) |<---(E)------- Script ---------<| | | | +---------------+ +-|--------+ | | (A) (G) Access Token | | ^ v +---------+ | | | Client | | | +---------+ implicit grant browser Facebook Auth website server website User Facebook connect
  • 13. Implicit Grant supported by •facebook (behind sdk) •google •soundcloud •box.net •windows live ! •& more
  • 15. Abstractions •session manager (controller) •Oauth adapter •live, FB specific adapters •popup manager
  • 16. 6 <div {{bind-attr class=":sign-in-menu isOpen:open:closed"}}> 7 <a class="sign-in-button facebook" href="#" {{action "selectService" "facebook"}}> 8 Sign In with Facebook 9 </a> 10 <a class="sign-in-button windows" href="#" {{action "selectService" "live"}}> 11 Sign In with Windows Live 12 </a> 13 <div class="mobile-show menu-footer subheader"> 14 {{link-to 'Leaderboard' 'leaderboard'}} 15 {{link-to 'About' 'map.about'}} 16 </div> 17 </div>
  • 17. 36 signIn: function(service){ 37 var session = this.get('session'), 38 route = this; 39 session.open(service) 40 .then(function(){ 41 if (route.router.isActive('map')) { 42 route.disconnectOutlet({ 43 outlet: 'prompt', 44 parentView: 'map/neighborhood' 45 }); 46 } 47 var lastTransition = session.get('afterRedirect'); 48 if (lastTransition) { 49 lastTransition.retry(); 50 } else if (route.router.isActive('sign_in')) { 51 route.transitionTo(''); 52 } 53 }).catch(Ember.Logger.error); 54 },
  • 18. 61 Ember.Application.initializer({ 62 name: 'authentication', 63 initialize: function(container, app){ . . . 65 import Session from 'appkit/controllers/session'; 66 container.register('session:main', Session); 67 app.inject('controller', 'session', 'session:main'); 68 app.inject('route', 'session', 'session:main'); . . . 95 }); inject session
  • 19. 9 open: function(credentials){ 10 var session = this; 11 session.set('isAuthenticating', true); 12 13 return this.get('adapter').open(credentials, this) 14 .then(function(user){ 15 session.setProperties({ 16 isAuthenticated: true, 17 currentUser: user 18 }); 19 return user; 20 }).catch(function(err){ 21 if (err === 'canceled') { 22 return; // no-op 23 } else { 24 return Ember.RSVP.reject(err); 25 } 26 }).finally(function(){ 27 session.set('isAuthenticating', false); 28 }); 29 }, opening a session
  • 20. 61 Ember.Application.initializer({ 62 name: 'authentication', 63 initialize: function(container, app){ . . . 70 import Auth from 'appkit/models/auth'; 71 container.register('session:adapter', Auth); 72 app.inject('session:adapter', 'store', 'store:main'); 73 app.inject('session:main', 'adapter', 'session:adapter'); . . . 95 }); Inject Auth adapter
  • 21. 50 // returns a promise that resolves to a user 51 open: function(serviceName){ 52 var auth = this; 53 var authService = this.container.lookup('auth:' + serviceName); 54 55 if (!authService) { 56 return Ember.RSVP.reject('unrecognized service auth:' + 57 serviceName); 58 } else { 59 return authService.open() 60 .then( function(serviceData) { 61 // create a session 62 var sessionData = { 63 authData: { 64 name: serviceData.name, 65 id: serviceData.id, 66 accessToken: serviceData.accessToken 67 } 68 }; 69 var session = auth.get('store').createRecord('session', 70 sessionData); 71 return session.save(); 72 }).then( function(session){ 73 auth.set('authToken', session.get('id')); 74 75 return session.get('user'); 76 }); 77 } 78 }, open an auth attempt
  • 22. 25 var LiveAuthService = Ember.Object.extend({ 26 open: function(){ 27 return this.signIn() 28 .then( this.normalizeServiceData ); 29 }, 30 31 signIn: function(){ 32 var url = createAuthUrl(); 33 return this.get('popup'). 34 open(url, {width: 500, height: 510 }); 35 }, 36 37 normalizeServiceData: function(accessToken){ 38 return { 39 name: 'live', 40 accessToken: accessToken 41 }; 42 } 43 }); open windows live auth attempt
  • 23. 38 App.initializer({ 39 name: 'Register Services', 40 initialize: function(container, app) { 41 registerServices(container); 42 43 // force creation of FacebookAuthService (to load the FB global) 44 container.lookup('auth:facebook'); 45 46 app.inject('auth', 'popup', 'popups:authenticate'); 47 } 48 }); Inject popup service
  • 24. 65 open: function(url, options) { 66 this.closeExistingWindow(); 67 this.rejectExistingDeferred('canceled'); 68 var deferred = this.generateNewDeferred(); 69 var defaultedOptions = this.applyDefaultOptions(options); 70 this.popup = window.open( 71 url, 'authentication', parameterizeOptions(defaultedOptions) 72 ); 73 74 if (this.popup) { 75 this.popup.focus(); 76 $(window).on('message', this.boundMessageHandler); 77 } else { 78 this.rejectExistingDeferred('failed to open popup'); 79 } 80 81 return deferred.promise; 82 },
  • 25. 30 createBoundMessageHandler: function(){ 31 this.boundMessageHandler = function(event){ 32 var matches, message = event.originalEvent.data; 33 if (!message || !(matches = message.match(/^setAccessToken:(.*)/))){ 34 return; 35 } 36 37 if (matches[1]){ 38 Ember.run(this, function(){ 39 this.closeExistingWindow(); 40 this.resolveExistingDeferred(matches[1]); 41 }); 42 } 43 }.bind(this); 44 }.on('init'), Listen for messages from the popup
  • 26. Upon load, look for tokens 61 Ember.Application.initializer({ 62 name: 'authentication', 63 initialize: function(container, app){ . . . 75 // Kind of feels like the in-popup logic should be elsewhere 76 var auth = container.lookup('session:adapter'); 77 var token = auth.readAccessToken(); 78 if (token && window.opener) { 79 // Don't go forward, we are just a popup with an accessToken 80 app.deferReadiness(); 81 window.opener.postMessage( 82 'setAccessToken:'+token, 83 Overherd.settings.origin 84 ); 85 } . . . 94 } 95 });
  • 27. Upon load, look for tokens 99 readAccessToken: function(){ 100 var accessToken, match, 101 regex = /access_token=([^&]*)/, 102 hash = window.location.hash; 103 104 if (window.location.hash){ 105 hash = window.location.hash; 106 if (match = hash.match(regex)) { 107 return match[1]; 108 } 109 } 110 }
  • 29. Other ideas •localstorage for auth tokens •how to recognize a cancelled sign in? •we still check the token is valid server-side