为什么每次在地址栏中更改 URL 时我的当前客户端服务都会重建?

Why does my current-client service get rebuilt everytime the URL is changed in the address bar?

我在 Ember 中有一个 current-client 服务,旨在从数据库中提取当前用户的信息并将其存储在服务中,以便在整个应用程序中使用。只要我点击导航菜单链接,当前用户信息就会被保存下来。但是,当更改地址栏中的 URL 时,当前用户被删除,服务必须返回并再次获取信息。

为什么会发生这种情况,我该如何防止这种情况发生?

更新: 我正在使用来自 Ember-Simple-Auth 的 authenticationMixins。理想情况下,所提供的解决方案不会对此产生影响。例如,当客户端通过身份验证并登录时,如果他们尝试导航到登录页面,那么他们应该被路由到索引页面。或者,如果未经身份验证的客户端试图通过仅键入 URL 来导航到受保护的页面,则应用程序应该对用户进行身份验证,然后将他们路由到他们最初尝试导航到的页面(不强制用户重新导航)。

更新 2: 具体来说,被清除的信息是客户是否已成功完成他们的 2FA(即,isTwoFactorAuthenticated 从 True 变为 False) .这会影响我们根据客户端是否同时通过身份验证和 2FA 完成绘制的导航菜单。换句话说,导航菜单是错误的,因为它使客户端看起来像是已注销,尽管实际上并没有。

服务:当前-client.js

import Service, { inject as service } from '@ember/service';

export default Service.extend({

    store: service('store'),

    isTwoFactorAuthenticated: false,

    twoFactorCodeSendMethod: null,

    client: null,

    loadCurrentClient() {

        this.get('store').queryRecord('client', {me: true})
        .then((client) => {

            this.set('client', client);
        });
    },
});

路线: Application.js

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default Route.extend({

    session: service('session'),
    currentClient: service('current-client'),

    beforeModel() {

        this._super(... arguments);
        this.loadCurrentClient();
    },

    activate() {

        this._super(...arguments);

        document.body.classList.add('gray-bg');
    }, 

    init() {

        this._super(... arguments);

        this.get('session').on('authenticationSucceeded', () => {

            this.loadCurrentClient();

            this.get('currentClient').set('twoFactorCodeSendMethod', null);
            this.get('currentClient').set('isTwoFactorAuthenticated', false);
        }),

        this.get('session').on('invalidationSucceeded', () => {

            this.get('currentClient').set('client', null);
            this.get('currentClient').set('isTwoFactorAuthenticated', false);
            this.get('currentClient').set('twoFactorCodeSendMethod', null);

            window.location.replace('/clients/login');
        });
    },

    loadCurrentClient() {

        if(this.get('session').get('isAuthenticated')) {

            this.get('currentClient').loadCurrentClient();
        }
    },
});

由于您已经在使用 ember-simple-auth,因此您可以使用 store/cache the data. This will tie it to authentication so when the user logs out the data is also removed. By default ember-simple-auth stores session data in local storage 的会话服务,该服务即使在浏览器关闭时仍然存在,您可能需要对其进行自定义以满足您的要求。

import Service, { inject as service } from '@ember/service';

export default Service.extend({
  session: service(),
  store: service(),

  isTwoFactorAuthenticated: computed('session.data.isTwoFactorAuthenticated', {
    get() {
      return this.session.data.isTwoFactorAuthenticated || false;
    },
    set(key, value) {
      this.session.set('data.isTwoFactorAuthenticated', value);
      return value;
    }
  }),

  twoFactorCodeSendMethod: null,

  client: null,

  loadCurrentClient() {
    if (this.session.data.client) {
      this.client = this.session.data.client;
      return;
    }

    this.get('store').queryRecord('client', {me: true})
     .then((client) => {
       this.set('client', client);
       this.session.set('data.client', client);
    });
  },
});