SlideShare uma empresa Scribd logo
1 de 31
Baixar para ler 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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
 

Último

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 

Último (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 

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