使用 Firebase 简单登录保护路由 [英] Protecting a route using Firebase Simple Login

查看:16
本文介绍了使用 Firebase 简单登录保护路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement the following sequence of events in an Ember app that uses Firebase Simple Login and ember-cli.

  1. 在允许进入任何路由之前检查用户是否已通过身份验证.所有路由都需要进行身份验证.
  2. 如果用户未通过身份验证,则重定向到 LoginRoute.如果用户通过了身份验证,则允许他们输入路由.
  1. Check if the user is authenticated before allowing entry to any route. All routes need to be authenticated.
  2. If the user is not authenticated, redirect to LoginRoute. If the user is authenticated, allow them to enter the route.

为了完成第 1 步,我在初始化程序中重新打开 Ember.Route 并实现一个 beforeModel 钩子.

In order to accomplish step 1, I reopen Ember.Route in an initializer and implement a 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.

The above code does indeed redirect to login if the user is not currently logged in.

LoginController 简单地实例化一个新的 FirebaseSimpleLogin 对象并注册适当的回调函数.

LoginController simply instantiates a new FirebaseSimpleLogin object and registers the appropriate callback function.

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 钩子在 authCompleted 回调完成之前执行,导致钩子重定向到 login.
  • When LoginController first initializes, isAuthed is set to false. Therefore, when authCompleted finishes, the app will always redirect to index.
  • The beforeModel hook executes before the authCompleted callback finishes, causing the hook to redirect to login.

页面刷新的结果是

  1. login 模板闪烁一秒钟.
  2. 应用程序转换为 index.
  1. The login template flashes for a second.
  2. The app transitions to index.

这会导致每次页面刷新丢失其当前位置(重定向到 index 路由).

This causes every page refresh to lose its current location (redirecting to the index route).

问题是,如何使用 Ember 和 Firebase 简单登录保护路由?任何帮助将不胜感激.

The question is, how can I protect a route using Ember and Firebase Simple Login? Any help would be appreciated.

推荐答案

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

Totally my opinion, but I like making the auth part of the resource tree. It doesn't need to be part of the url, but can be. Using this way, it can still use a global controller (it will be hooked up based on what's returned from the call, or some other hookup if you fetch it in the login).

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

在非承诺回调的情况下,您可以创建自己的承诺,并在适当的时候解决.

In the case of a non-promise callback, you can create your own promise, and resolve that when appropriate.

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});      
}

这篇关于使用 Firebase 简单登录保护路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆