我是 ember-cli 的新手,目前我在使用 LinkedIn 的 oauth2 时遇到问题,服务器端是 rails。这也是我的第一个问题,所以如果需要任何其他信息或者是否过于冗长,请告诉我。当我尝试登录时,我得到了linkedin弹出窗口,但随后出现以下错误:
POST http://localhost:9000/v1/sessions 400 (Bad Request)
jQuery.ajaxTransport.send @ jquery.js:9664jQuery.extend.ajax @ jquery.js:9215exports.default.Ember.default.Object.extend._fetchSession @ application.js:22initializePromise @ ember.debug.js:45486Promise @ ember.debug.js:47114_fetchSession @ application.js:21fetch @ application.js:15(anonymous function) @ session.js:72tryCatch @ ember.debug.js:45439invokeCallback @ ember.debug.js:45451(anonymous function) @ ember.debug.js:47350(anonymous function) @ ember.debug.js:26472Queue.invoke @ ember.debug.js:878Queue.flush @ ember.debug.js:943DeferredActionQueues.flush @ ember.debug.js:748Backburner.end @ ember.debug.js:173Backburner.run @ ember.debug.js:228Backburner.join @ ember.debug.js:247run.join @ ember.debug.js:15904run.bind @ ember.debug.js:15966jQuery.Callbacks.fire @ jquery.js:3148jQuery.Callbacks.self.fireWith @ jquery.js:3260jQuery.extend.ready @ jquery.js:3472completed @ jquery.js:3503
当我实际点击“使用linkedin 登录”按钮时,我得到了相同的响应。
这是我的 ember-cli 代码:
应用程序/适配器/application.js
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
namespace: 'v1'
});
应用程序/路由/application.js
import Ember from 'ember';
//takes place of App.IndexRoute =
export default Ember.Route.extend({
//allow session to persist after page refreshes & fetch wehn activated
//shoudl only happen once
activate: function() {
this.get('session').fetch();
},
actions: {
signInViaLinkedin: function(){
var route = this;
this.get('session').open('linked-in-oauth2').then(function(authorization){
// do the things after login, like redirect to dashboard
}, function(error) {
route.controller.set('error', 'Could not sign you in: ' + error.message);
});
}
}
});
配置/环境.js
module.exports = function(environment) {
var ENV = {
modulePrefix: 'fetch',
environment: environment,
baseURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
}
};
...
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
ENV.APP.LOG_VIEW_LOOKUPS = true;
ENV.puppifi = {
sessionUrl: 'http://localhost:9000/v1/sessions'
};
ENV.torii = {
sessionServiceName: 'session',
providers: {
'linked-in-oauth2': {
apiKey: 'LINKED_IN_CLIENT_ID',
redirectUri: 'http://localhost:4200',
}
}
};
if (environment === 'test') {
// Testem prefers this...
ENV.baseURL = '/';
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
}
if (environment === 'production') {
ENV.torii = {
sessionServiceName: 'session',
providers: {
'linked-in-oauth2': {
apiKey: 'LINKED_IN_CLIENT_ID',
redirectUri: 'http://http://development.fetch.divshot.io',
}
}
};
ENV.puppifi ={
sessionUrl: '/__/proxy/v1/sessions'
};
}
return ENV;
}
};
Rails 应用程序
应用程序/控制器/v1/sessions_controller.rb
module V1
# session controller can fetch old sessions
class SessionsController < ApplicationController
# skipped because ember and rails are on different domains
skip_before_action :verify_authenticity_token
def create
linkedin_authenticator = LinkedinAuthenticator.new(linkedin_auth_code)
user_factory = UserFactory.new(linkedin_authenticator)
user_factory.find_or_create_user
render json: user, status: :created
end
private
def linkedin_auth_code
params.require(:'linkedin_auth_code')
end
end
结尾
服务/linkedin_authenticator.rb
require "net/http"
require "net/https"
class LinkedinAuthenticator
LINKED_IN_OAUTH_PATH = "https://linkedin.com/uas/oauth2/authorization?response_type=code"
def initialize(auth_code)
@auth_code = auth_code
end
def name
linkedin_user[:login]
end
private
def linkedin_user
@linkedin_user ||= linkedin_client.user
end
def linkedin_client
OAuth2::Client.new(access_token: access_token)
end
def access_token
linkedin_response["access_token"]
end
def token_type
linkedin_response["token_type"]
end
def scope
linkedin_response["scope"]
end
def linkedin_response
@linkedin_response ||= JSON.parse(res.body)
end
def res
http.request(req)
end
def req
req = Net::HTTP::Post.new(uri.path)
req.set_form_data(post_data)
req["Accept"] = "application/json"
req
end
def http
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http
end
def uri
URI.parse(LINKED_IN_OAUTH_PATH)
end
def post_data
{
"client_id" => ENV["LINKED_IN_CLIENT_ID"],
"client_secret" => ENV["LINKED_IN_CLIENT_SECRET"],
"code" => @auth_code
}
end
end