【问题标题】:Ember Simple Auth (Devise) after update, authenticate breakEmber Simple Auth (Devise) 更新后,认证中断
【发布时间】:2015-02-09 05:10:21
【问题描述】:

我使用 Ember Simple Auth(不是 Ember CLI 版本)进行了从 0.6.4 到 0.7.2 的更新以进行设计,现在我的身份验证根本不起作用 :(,你有什么想法吗?非常感谢为您的帮助:)

PS : 显然,在 authenticate_with_http_token 执行 |token, options| 之后,ApplicationController (application_controller.rb) 不会继续。并且 authenticate_with_http_token 为空(用 puts 测试)

login_controller.js

App.LoginController = Ember.Controller.extend(SimpleAuth.LoginControllerMixin, {
  authenticator: 'simple-auth-authenticator:devise'
  //authenticator: 'authenticator:custom'
});

application.js.coffee

Ember.Application.initializer
  name: "authentication"
  after: "simple-auth"
  initialize: (container, application) ->
    applicationRoute = container.lookup("route:application")
    session = container.lookup("simple-auth-session:main")
    # handle the session events
    session.on "sessionAuthenticationSucceeded", ->

      applicationRoute.transitionTo "Myspace"
      return

    return

window.ENV = window.ENV || {}
window.ENV["simple-auth"] = { store: 'simple-auth-session-store:local-storage', authorizer: "simple-auth-authorizer:devise" };
window.ENV['simple-auth-devise'] = {
    crossOriginWhitelist: ['*'], 
    serverTokenEndpoint: 'users/sign_in',
  };

login.hbs

<br />
<div class="row">
    <div class="large-12 columns">
        <form {{action 'authenticate' on='submit'}}>
          <label for="identification">Login</label>
          {{input id='identification' placeholder='Enter Login' value=identification}}
          <label for="password">Password</label>
          {{input id='password' placeholder='Enter Password' type='password' value=password}}
          <button type="submit">Login</button>
        </form>
    </div>
</div>

login_route.js.coffee

App.LoginRoute = Ember.Route.extend(

  #model: (params) ->
    #return @store.find('user', @get('session.user_id'))

  setupController: (controller, model) ->
    #controller.set "content", model
    controller.set "errorMessage", null
    return

  actions:
    sessionAuthenticationFailed: (responseBody) ->
      message = responseBody.error
      @controller.set "errorMessage", message
      console.log "errorMessage : " + message
      return )

myspace_route.js.coffee

App.MyspaceRoute = Ember.Route.extend(SimpleAuth.AuthenticatedRouteMixin,  ....)

session_controller.rb

class SessionsController < Devise::SessionsController
  def create
    respond_to do |format|
      format.html { super }
      format.json do
        self.resource = warden.authenticate!(auth_options)
        sign_in(resource_name, resource)
        data = {
          user_token: self.resource.authentication_token,
          user_email: self.resource.email
        }
        render json: data, status: 201
      end
    end
  end
end

application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :null_session,
      if: Proc.new { |c| c.request.format =~ %r{application/json} }

  before_filter :skip_trackable, :authenticate_user_from_token!

  private

    def skip_trackable
      request.env['warden'].request.env['devise.skip_trackable'] = '1'
    end

    def authenticate_user_from_token!
      puts "authentification"
      puts authenticate_with_http_token
      authenticate_with_http_token do |token, options|
        user_email = options[:user_email].presence
        user       = user_email && User.find_by_email(user_email)
        puts "user.authentication_token"
        puts user.authentication_token
        puts token
        puts "token"
        if user && Devise.secure_compare(user.authentication_token, token)
          sign_in user, store: false
        end
      end
    end
end

【问题讨论】:

  • 您可以在应用程序路由中实现sessionAuthenticationSucceeded(当您使用ApplicationRouteMixin 时),而不是在初始化程序中列出会话事件 - 使其更简单。
  • 是的,很好的建议 :),谢谢 :)

标签: ruby-on-rails ember.js devise coffeescript ember-simple-auth


【解决方案1】:

您在 'simple-auth' 初始化程序之后运行的初始化程序中设置 window.ENV 对象,因此 Ember Simple Auth 实际上无法看到您在其初始化程序运行时设置的值。确保在'simple-auth' 初始化程序运行之前设置这些值。

当然你也应该切换到 Ember CLI ;)

【讨论】:

  • 提出了哪些请求?如果提出请求,会有什么反应?有没有发现任何错误?
  • 没有javascript错误,我的下一篇文章我给你更多细节,这是一个简单的表单登录请求
【解决方案2】:

运行调试器后,它转到:

ember-simple-auth.js

authenticate: function() {
    var args          = Array.prototype.slice.call(arguments);
    var authenticator = args.shift();
    Ember.assert('Session#authenticate requires the authenticator factory to be specified, was ' + authenticator, !Ember.isEmpty(authenticator));
    var _this            = this;
    var theAuthenticator = this.container.lookup(authenticator);
    Ember.assert('No authenticator for factory "' + authenticator + '" could be found', !Ember.isNone(theAuthenticator));
    return new Ember.RSVP.Promise(function(resolve, reject) {
      theAuthenticator.authenticate.apply(theAuthenticator, args).then(function(content) {
        _this.setup(authenticator, content, true);
        resolve(); // <- it goes to here
      }, function(error) {
        _this.clear();
        _this.trigger('sessionAuthenticationFailed', error);
        reject(error);
      });
    });
  },

带有令牌的 json 响应似乎还可以,身份验证器配置似乎也可以...

我在这个承诺中也有一个“拒绝”

ember-simple-auth.js

 restore: function() {
        var _this = this;
        return new Ember.RSVP.Promise(function(resolve, reject) {
          var restoredContent = _this.store.restore();
          var authenticator   = restoredContent.authenticator;
          if (!!authenticator) {
            delete restoredContent.authenticator;
            _this.container.lookup(authenticator).restore(restoredContent).then(function(content) {
              _this.setup(authenticator, content);
              resolve();
            }, function() {
              _this.store.clear();
              reject();
            });
          } else {
            _this.store.clear();
            reject();
          }
        });
      },

被拒绝的承诺的痕迹:

VM7522:164 Ember Inspector (Promise Trace): 
    at new Promise (http://localhost:3000/assets/ember.js?body=1:10174:9)
    at __exports__.default.Ember.ObjectProxy.extend.restore (http://localhost:3000/assets/ember-simple-auth.js?body=1:1116:16)
    at __exports__.default (http://localhost:3000/assets/ember-simple-auth.js?body=1:1337:15)
    at __exports__.default.initialize (http://localhost:3000/assets/ember-simple-auth.js?body=1:447:9)
    at http://localhost:3000/assets/ember.js?body=1:43164:11
    at visit (http://localhost:3000/assets/ember.js?body=1:43556:7)
    at DAG.topsort (http://localhost:3000/assets/ember.js?body=1:43610:11)
    at Namespace.extend.runInitializers (http://localhost:3000/assets/ember.js?body=1:43161:15)
    at Namespace.extend._initialize (http://localhost:3000/assets/ember.js?body=1:43046:14)

编辑1:还有这个:

ember-simple-auth-devise.js

  restore: function(properties) {
    var _this            = this;
    var propertiesObject = Ember.Object.create(properties);
    return new Ember.RSVP.Promise(function(resolve, reject) {
      if (!Ember.isEmpty(propertiesObject.get(_this.tokenAttributeName)) && !Ember.isEmpty(propertiesObject.get(_this.identificationAttributeName))) {
        resolve(properties);
      } else {
        reject();
      }
    });
  },

有迹可循:

 Ember Inspector (Promise Trace): 
    at new Promise (http://localhost:3000/assets/ember.js?body=1:10174:9)
    at __exports__.default.Base.extend.restore (http://localhost:3000/assets/ember-simple-auth-devise.js?body=1:156:16)
    at apply (http://localhost:3000/assets/ember.js?body=1:7993:27)
    at superWrapper [as restore] (http://localhost:3000/assets/ember.js?body=1:7571:15)
    at http://localhost:3000/assets/ember-simple-auth.js?body=1:1121:51
    at invokeResolver (http://localhost:3000/assets/ember.js?body=1:10192:9)
    at new Promise (http://localhost:3000/assets/ember.js?body=1:10178:9)
    at __exports__.default.Ember.ObjectProxy.extend.restore (http://localhost:3000/assets/ember-simple-auth.js?body=1:1116:16)
    at __exports__.default (http://localhost:3000/assets/ember-simple-auth.js?body=1:1337:15)

【讨论】:

  • 如果restore 返回的promise 被拒绝,这意味着会话数据中缺少某些内容,或者某个属性的名称可能有误...
  • 我会检查的!谢谢你。也许我的 Rails 用户序列化器?
  • 其实ember_simple_auth:session当我get('session')是存在的,但是_lastData是空的……get('session.user_token')或者get中找不到user_token也没有user_email ('session').get('store').get('user_token') ...我检查了所有参数,我真的不明白为什么它不起作用。谢谢你的帮助@marcoow PS:另外,感谢你在这个项目上的工作,它非常有帮助,是 ember 的必备物品
  • 在会话的authenticate 方法中检查content_this.setup(authenticator, content, true); 中的内容。
  • sessions: Array[3] 0: Array[2] 0: "user_id" 1: 2 length: 2 __proto__: Array[0] 1: Array[2] 0: "user_token" 1: "koGRTMTuG6DzmL-j94xr" length: 2 __proto__: Array[0] 2: Array[2] 0: "user_email" 1: "thxxxx@gmail.com"
【解决方案3】:

在marcoow的帮助下,把https://github.com/simplabs/ember-simple-auth/tree/master/packages/ember-simple-auth-devise#server-side-setupSessionsController修改成这样:

class SessionsController < Devise::SessionsController
  def create
    respond_to do |format|
      format.html { super }
      format.json do
        self.resource = warden.authenticate!(auth_options)
        sign_in(resource_name, resource)
        @data = {
          user_token: self.resource.authentication_token,
          user_email: self.resource.email
        }
        render json: @data.to_json, status: 201
      end
    end
  end
end

现在可以了

编辑: to_json 解释:http://apidock.com/rails/ActiveRecord/Serialization/to_json

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2014-07-10
    • 1970-01-01
    相关资源
    最近更新 更多