2

我是 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
4

0 回答 0