Ember.js 登录后同步注入当前用户

Ember.js 登录后同步注入当前用户,ember.js,initializer,ember-simple-auth,Ember.js,Initializer,Ember Simple Auth,在我的EmberJS应用程序中,我有一个当前用户初始值设定项,它将用户注入到所有控制器、路由和视图中。登录后效果很好。我需要同步加载当前用户对象,这样我就可以立即检查一些用户权限 这是我的初始值设定项: App.CurrentUserInitializer - Ember.Initializer.extent({ name: 'current-user', after: 'authentication', initialize: function(container,

在我的EmberJS应用程序中,我有一个当前用户初始值设定项,它将用户注入到所有控制器、路由和视图中。登录后效果很好。我需要同步加载当前用户对象,这样我就可以立即检查一些用户权限

这是我的初始值设定项:

App.CurrentUserInitializer - Ember.Initializer.extent({

    name: 'current-user',
    after: 'authentication',

    initialize: function(container, app) {

      var store = container.lookup('store:main');

      app.deferReadiness();

      store.find('user', 'me').then(function (user) {

        app.register('session:user', user, {instantiate: false});

        _.forEach(['route', 'controller', 'view'], function (place) {
          app.inject(place, 'currentUser', 'session:user');
        });

        app.advanceReadiness();

      }).catch(function () {
        app.advanceReadiness();
      });
    }
});
这对我来说是在登录过程中出现故障的。当应用程序启动时,初始值设定项运行,但
/users/me
路由返回401错误。如果我没有捕捉到错误和先进性,引导就会停止。通过捕获错误,应用程序将启动,但在登录后不会再次运行初始值设定项,因此不会加载当前用户

我的选择是什么?我不能使用@Marcow推荐的向会话添加计算属性的方法,因为我需要在启动时加载用户

我曾尝试将用户对象强制加载到IndexRoute上,但这似乎不起作用


非常感谢任何提示。

我将注册一个
会话:当前
对象,其
用户
属性为空。这将被注入
控制器
路由
(不确定注入内部视图是否是个好主意)

因此,在启动时,
用户
是未知的,但用户查找是在路由器深入到
应用程序
路由之前完成的,根:

应用程序
路由的
beforeModel
钩子中,您将加载当前用户。然后:

  • 要么您得到了用户,然后将其设置为this.set('session.user',model)
  • 或者您将进入
    应用程序的
    错误
    钩子
    路径,在这种情况下,您必须检查原因,如果
    401
    ,则您可以将用户重定向到登录路径
    this.transition('login')
  • 如果您获得了
    401
    ,请不要忘记在
    session
    上设置一个标志,这样
    transition
    将使用户在到达
    登录路径之前不会再次查找
    beforeModel

    用于加载会话用户并对其进行初始化的代码可以放在
    会话:当前
    对象中,以便您可以从
    应用程序
    路由或
    登录
    控制器调用它

    例如,这是我的
    会话
    初始化器(与我解释的不完全一样,但加载到初始化器中,因此更接近您所看到的内容)。我使用了一个
    会话
    模型,这样我就做了
    /session/current
    ,然后让一个用户进入(或不进入)其中,该用户具有正确的id,而不是
    me
    ,这将使存储区用另一个id加载同一个用户,因此将同一用户作为两个不同记录的两倍:

    app/models/session.js

    import DS from 'ember-data';
    import Ember from 'ember';
    
    export default DS.Model.extend({
      user:            DS.belongsTo('user'),
      isAuthenticated: Ember.computed.bool('user.isClaimed')
    });
    
    import Ember from 'ember';
    
    export default {
      name:  'session',
      after: 'store',
    
      initialize: function (container, app) {
        var store = container.lookup('store:main'),
            sid = Ember.$.cookie('sid');
        // used to register a session
        var register = function (session) {
          app.register('session:main', session, {instantiate: false});
          app.inject('route', 'session', 'session:main');
          app.inject('controller', 'session', 'session:main');
        };
        // used to create a new session and trigger the backend to get details about it
        // useful if the server is able to give an existing session while the browser doesn't know about it
        // with external providers for example
        var newSession = function () {
          var session = store.createRecord('session');
          // be sure to wipe out any invalid session ID
          Ember.$.removeCookie('sid');
          register(session);
          return session.save().then(function (model) {
            // if we got a valid new session, save its ID
            Ember.$.cookie('sid', model.get('id'));
          }).catch(function () {
            Ember.debug('error saving new session: ' + Array.prototype.join.call(arguments, ', '));
          });
        };
        // overall logic ==================
        app.deferReadiness();
        if (sid) {
          // try to load the existing session
          store.find('session', sid).then(function (model) {
            register(model);
            app.advanceReadiness();
          }).catch(function () {
            // there was a cookie for the session but it might have expired or the server invalidated it
            Ember.debug('error loading session: ' + Array.prototype.join.call(arguments, ', '));
            newSession().finally(function () {
              app.advanceReadiness();
            });
          });
        }
        else {
          // we don't have any trace of a session, let's just create a new one
          newSession().finally(function () {
            app.advanceReadiness();
          });
        }
      }
    };
    
    import Ember from 'ember';
    
    var Router = Ember.Router.extend();
    
    Router.map(function () {
      this.resource('session', {path: '/'}, function(){
        this.route('login');
        this.route('logout');
      });
    });
    
    export default Router;
    
    app/initializers/session.js

    import DS from 'ember-data';
    import Ember from 'ember';
    
    export default DS.Model.extend({
      user:            DS.belongsTo('user'),
      isAuthenticated: Ember.computed.bool('user.isClaimed')
    });
    
    import Ember from 'ember';
    
    export default {
      name:  'session',
      after: 'store',
    
      initialize: function (container, app) {
        var store = container.lookup('store:main'),
            sid = Ember.$.cookie('sid');
        // used to register a session
        var register = function (session) {
          app.register('session:main', session, {instantiate: false});
          app.inject('route', 'session', 'session:main');
          app.inject('controller', 'session', 'session:main');
        };
        // used to create a new session and trigger the backend to get details about it
        // useful if the server is able to give an existing session while the browser doesn't know about it
        // with external providers for example
        var newSession = function () {
          var session = store.createRecord('session');
          // be sure to wipe out any invalid session ID
          Ember.$.removeCookie('sid');
          register(session);
          return session.save().then(function (model) {
            // if we got a valid new session, save its ID
            Ember.$.cookie('sid', model.get('id'));
          }).catch(function () {
            Ember.debug('error saving new session: ' + Array.prototype.join.call(arguments, ', '));
          });
        };
        // overall logic ==================
        app.deferReadiness();
        if (sid) {
          // try to load the existing session
          store.find('session', sid).then(function (model) {
            register(model);
            app.advanceReadiness();
          }).catch(function () {
            // there was a cookie for the session but it might have expired or the server invalidated it
            Ember.debug('error loading session: ' + Array.prototype.join.call(arguments, ', '));
            newSession().finally(function () {
              app.advanceReadiness();
            });
          });
        }
        else {
          // we don't have any trace of a session, let's just create a new one
          newSession().finally(function () {
            app.advanceReadiness();
          });
        }
      }
    };
    
    import Ember from 'ember';
    
    var Router = Ember.Router.extend();
    
    Router.map(function () {
      this.resource('session', {path: '/'}, function(){
        this.route('login');
        this.route('logout');
      });
    });
    
    export default Router;
    
    app/router.js

    import DS from 'ember-data';
    import Ember from 'ember';
    
    export default DS.Model.extend({
      user:            DS.belongsTo('user'),
      isAuthenticated: Ember.computed.bool('user.isClaimed')
    });
    
    import Ember from 'ember';
    
    export default {
      name:  'session',
      after: 'store',
    
      initialize: function (container, app) {
        var store = container.lookup('store:main'),
            sid = Ember.$.cookie('sid');
        // used to register a session
        var register = function (session) {
          app.register('session:main', session, {instantiate: false});
          app.inject('route', 'session', 'session:main');
          app.inject('controller', 'session', 'session:main');
        };
        // used to create a new session and trigger the backend to get details about it
        // useful if the server is able to give an existing session while the browser doesn't know about it
        // with external providers for example
        var newSession = function () {
          var session = store.createRecord('session');
          // be sure to wipe out any invalid session ID
          Ember.$.removeCookie('sid');
          register(session);
          return session.save().then(function (model) {
            // if we got a valid new session, save its ID
            Ember.$.cookie('sid', model.get('id'));
          }).catch(function () {
            Ember.debug('error saving new session: ' + Array.prototype.join.call(arguments, ', '));
          });
        };
        // overall logic ==================
        app.deferReadiness();
        if (sid) {
          // try to load the existing session
          store.find('session', sid).then(function (model) {
            register(model);
            app.advanceReadiness();
          }).catch(function () {
            // there was a cookie for the session but it might have expired or the server invalidated it
            Ember.debug('error loading session: ' + Array.prototype.join.call(arguments, ', '));
            newSession().finally(function () {
              app.advanceReadiness();
            });
          });
        }
        else {
          // we don't have any trace of a session, let's just create a new one
          newSession().finally(function () {
            app.advanceReadiness();
          });
        }
      }
    };
    
    import Ember from 'ember';
    
    var Router = Ember.Router.extend();
    
    Router.map(function () {
      this.resource('session', {path: '/'}, function(){
        this.route('login');
        this.route('logout');
      });
    });
    
    export default Router;
    
    app/templates/application.hbs(例如):

    欢迎使用我的应用程序
    {{{#如果session.isAuthenticated}
    注销
    {{else}
    {{{#链接到'session.login'}登录{{/链接到}
    {{/if}
    {{outlet}}
    

    然后,一旦进入登录控制器,当用户实际登录时,服务器将返回
    会话
    模型,并将用户链接到该模型中,因此余烬绑定魔法将只更新会话对象。

    @Huafu您有可以显示的代码示例吗?仅供参考-我使用的是ember simple auth,每当我在应用程序路径上使用beforeModel时,启动都会停止,即使返回了已履行的承诺。啊,如果您使用的是
    ember simple auth
    ,那么您应该在问题中告诉它,因为我不确定它是如何工作的,但它肯定会使我的部分答案无效。我将添加一个示例,但它没有简单的auth。我听说过SimpleAuth,但没有使用它,所以不能给出一个例子。是的,在
    beforeModel
    钩子中加入承诺的目的是暂停路由器,可能是简单的身份验证以某种方式停止引导,但通常一旦承诺实现,它应该继续boot@ToddSmithSalter,刚刚使用initialiser更新;-)令人惊叹的。谢谢你的例子。抱歉,我已将问题标记为ember simple auth。下次我会说得更清楚。哦,我的错!没有注意标签!