问题
I am trying to set up an authenticator which would be valid for many providers, because in the backend I am using doorkeeper assertion method which handles the whole flow.
I have installed:
* "ember-cli-simple-auth": "0.8.0-beta.1"
* "ember-cli-simple-auth-oauth2": "^0.8.0-beta.2"
* "ember-cli-simple-auth-torii": "^0.8.0-beta.2"
* "torii": "^0.3.4"
I was looking at this issue Workflow for Ember-simple-auth, Torii and Facebook Oauth2 so I could write this:
# templates/login
<a {{action 'oauth2Authenticate' 'facebook-oauth2'}}>Login with facebook</a>
<a {{action 'oauth2Authenticate' 'google-oauth2'}}>Login with google</a>
# controllers/login
actions: {
oauth2Authenticate: function(provider) {
this.get('session').authenticate('authenticator:oauth2', { torii: this.get('torii'), provider: provider });
}
}
# initializers/authentication
import Oauth2Authenticator from '../authenticators/oauth2';
export function initialize(container) {
container.register('authenticator:oauth2', Oauth2Authenticator);
}
export default {
name: 'authentication',
initialize: initialize
};
# authenticators/oauth2
import Ember from 'ember';
import OAuth2 from 'simple-auth-oauth2/authenticators/oauth2';
export default OAuth2.extend({
authenticate: function(options) {
var self = this;
console.log(options.provider);
return new Ember.RSVP.Promise(function(resolve, reject) {
options.torii.open(options.provider).then(function(data) {
var data = {
grant_type: 'assertion',
provider: options.provider,
assertion: data.authorizationCode
};
self.makeRequest(self.serverTokenEndpoint, data).then(function(response) {
Ember.run(function() {
var expiresAt = self.absolutizeExpirationTime(response.expires_in);
self.scheduleAccessTokenRefresh(response.expires_in, expiresAt, response.refresh_token);
resolve(Ember.$.extend(response, { expires_at: expiresAt }));
});
}, function(xhr, status, error) {
Ember.run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
}, reject);
});
}
});
# config/environment
ENV['simple-auth'] = {
authorizer: 'simple-auth-authorizer:oauth2-bearer',
crossOriginWhitelist: ['*']
};
ENV['simple-auth-oauth2'] = {
serverTokenEndpoint: ENV.host + '/oauth/token',
refreshAccessTokens: true
};
ENV['torii'] = {
providers: {
'facebook-oauth2': {
apiKey: '631252926924840',
redirectUri: 'http://localhost:4200'
},
'google-oauth2': {
apiKey: '631252926924840',
redirectUri: 'http://localhost:4200'
}
}
};
- POST /oauth/token: I pass to server the following params: 1. grant_type="assertion" 2. provider 3. assertion="3dPartyToken"
I am not sure if it is the better way for my requirements, for now I am getting the problem that I cannot run open method of torii, anybody know what I am doing wrong? if you have a better solution to this issue would be very appreciated.
error:
回答1:
You shouldn't extend the OAuth 2.0 authenticator to authenticate with torii as OAuth 2.0 and torii are very different from an Ember Simple Auth point of view although most of the torii providers connect to OAuth 2.0 backends. Simply use the torii authenticator and pass the torii provider that you want to use as the 2nd argument to Session.authenticate
. See this example to get an idea for how that works.
回答2:
Currently I'm using a similar approach as described in the question, but I inject torii
into my authenticator via an initializer:
export default {
name: 'custom-torii-oauth2-config',
before: 'simple-auth',
after: 'torii',
initialize: function(container, application) {
application.inject('authenticator:custom-torii-oauth2', 'torii', 'torii:main');
}
};
After that it can be used within the authenticator like following:
this.torii.open(...)
I also thought about the solution marcoow mentioned in his comment, but for me it results in to much duplicate code with the oauth2-authenticator
. Wouldn't an extension for the torii-authenticator
be nice, which is handling exactly this flow?
Edit
Important part of custom-torii-oauth2
authenticator.
fetchOauthData: function(options) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
_this.torii.open(options.provider).then(function(oauthData) {
Ember.run(function() {
resolve({
grant_type: 'authorization_code',
provider: oauthData.provider,
code: oauthData.authorizationCode,
});
});
}, function(error) {
Ember.run(function() {
reject(error);
});
});
});
}
来源:https://stackoverflow.com/questions/29851214/ember-cli-torii-and-multiple-providers