ember.js - 使用 Firebase Simple Login 保护路由

标签 ember.js firebase emberfire

我正在尝试在使用 Firebase Simple Login 和 ember-cli 的 Ember 应用中实现以下事件序列.

  1. 在允许进入任何路由之前检查用户是否经过身份验证。 所有路由都需要进行身份验证。
  2. 如果用户未通过身份验证,则重定向至 LoginRoute 。如果用户通过身份验证,则允许他们输入路线。

为了完成步骤 1,我重新打开 Ember.Route在初始化程序中并实现 beforeModel钩子(Hook)。

`import LoginController from "tracking/controllers/login"`

AuthInitializer =
  name: 'authInitializer'

  initialize: (container, application) ->
    # Register LoginController with all controllers/routes
    application.register 'main:auth', LoginController
    application.inject 'route', 'auth', 'main:auth'
    application.inject 'controller', 'auth', 'main:auth'
    application.inject 'main:auth', 'store', 'store:main'

    # Ensure user is logged in before allowing entry
    Ember.Route.reopen
      beforeModel: (transition) ->
        @transitionTo 'login' if !@get('auth.isAuthed')

`export default AuthInitializer`

上面的代码确实重定向到 login如果用户当前未登录。

LoginController只需实例化一个新的 FirebaseSimpleLogin对象并注册适当的回调函数。

LoginController = Ember.ObjectController.extend
  # Some of the controller is omitted for brevity...

  auth: null
  isAuthed: false

  init: ->
    dbRef = new Firebase('https://dawnbreaker.firebaseio.com')
    @set('auth', new FirebaseSimpleLogin(dbRef, @authCompleted.bind(@)))
    @_super()

  authCompleted: (error, user) ->
    if error
      # Handle invalid login attempt..
    else if user
      # Handle successful login..
      unless @get('isAuthed')
        @set('currentUserId', user.id)
        @set('isAuthed', true)
        @transitionToRoute('index')
    else
      # Handle logout..
      @set('currentUserId', null)
      @set('isAuthed', false)

`export default LoginController`

我的实现有两个问题。

  • 何时 LoginController首先初始化,isAuthed设置为 false。因此,当 authCompleted完成后,应用程序将始终重定向到 index .
  • beforeModel钩子(Hook)在authCompleted之前执行回调完成,导致钩子(Hook)重定向到 login .

页面刷新的结果是

  1. login模板闪烁一秒钟。
  2. 应用程序转换为 index .

这会导致每个页面刷新都会丢失其当前位置(重定向到 index 路线)。

问题是如何使用 Ember 和 Firebase Simple Login 保护路由?任何帮助将不胜感激。

最佳答案

完全是我的意见,但我喜欢将身份验证作为资源树的一部分。它不需要是 url 的一部分,但可以是。使用这种方式,它仍然可以使用全局 Controller (它将根据调用返回的内容进行连接,或者如果您在登录中获取它,则可以使用其他一些连接)。

App.Router.map(function() {
  this.resource('auth', {path:''}, function(){
    this.resource('foo');
    this.resource('bar', function(){
      this.route('baz')
    });
  });
  this.route('login');
});

App.AuthRoute = Em.Route.extend({
  model: function(params, transition){
    var self = this;
    // you can skip calling back with a local property
    return $.getJSON('/auth').then(function(result){
      if(!result.good){
        self.transitionTo('login');
      }
      return result;
    });
  }
}); 

http://emberjs.jsbin.com/OxIDiVU/668/edit

对于非 Promise 回调,您可以创建自己的 Promise,并在适当的时候解决该问题。

model: function(){
  var defer = Ember.RSVP.defer(),
      firebase = new Firebase('https://dawnbreaker.firebaseio.com'),
      fbLogin = new FirebaseSimpleLogin(firebase, this.authCompleted.bind(this));


  this.setProperties({
      defer: defer, 
      firebase: firebase,
      fbLogin: fbLogin
  });

  return defer.promise.then(function(result){
    // maybe redirect if authed etc...
  });
},
authCompleted: function(error, user){
  var defer = this.get('defer');
  //if authenticated
  defer.resolve({auth:true});      
  //else authenticated
  defer.resolve({auth:false});      
}

关于ember.js - 使用 Firebase Simple Login 保护路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24234810/

相关文章:

javascript - Firebase 函数通过 appVersion 或 session_start 触发 Analytics?

firebase - 甚至没有运行应用程序,Firestore 数据库读取就在增加

java - 在将图像上传到 Firebase 存储之前压缩图像

javascript - Ember cli 应用程序具有不同的适配器类型?

javascript - Ember 阵列 Controller 中长列表的内存问题

javascript - 关于 Ember 资源与路由的混淆

javascript - 在 Emberjs 中使用每个数据显示嵌套的 json 数据

javascript - Ember.js - 使用 EmberFire 从 Firebase 中删除数据

使用 Emberfire 和 Torii 进行 Firebase 3 身份验证